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

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 CHANGED
@@ -1578,6 +1578,19 @@ type CIAMProviderConfig = {
1578
1578
  claimsAsEntitlements?: ClaimsAsEntitlements;
1579
1579
  /** ConfigSource-only IdP assignment workflow used when IAM assignment is `'idp'`. */
1580
1580
  accessRequests?: AccessRequestsDestination;
1581
+ /**
1582
+ * Microsoft only. Which Entra tenants may sign in when the provider uses a
1583
+ * multi-tenant authority (`/common`, `/organizations`, `/consumers`). Entra mints
1584
+ * tenant-scoped issuers (`https://login.microsoftonline.com/{tid}/v2.0`), so no
1585
+ * single `authority` can be compared by strict equality; this constrains the
1586
+ * accepted `tid` instead.
1587
+ *
1588
+ * `'any'` (default) accepts any work/school tenant and personal accounts,
1589
+ * `'consumers'` accepts only personal Microsoft accounts, and an array accepts
1590
+ * only the listed tenant GUIDs. Ignored when `authority` names a single tenant —
1591
+ * that keeps the strict-equality check.
1592
+ */
1593
+ allowedTenants?: "any" | "consumers" | string[];
1581
1594
  };
1582
1595
  /** Sanitized provider entry returned by the discovery endpoint for the UI. */
1583
1596
  type CIAMProviderDescriptor = {
@@ -2048,7 +2061,7 @@ type WorkloadClientDescription = {
2048
2061
  idpTokenUrl?: string;
2049
2062
  scope?: string;
2050
2063
  audience?: string;
2051
- authMethod: "client_secret" | "private_key_jwt" | "server_only";
2064
+ authMethod: "client_secret" | "federated_token" | "managed_identity" | "private_key_jwt" | "server_only";
2052
2065
  };
2053
2066
  type WorkloadDescription = ModuleDescriptionBase<"workload"> & {
2054
2067
  incoming: {
@@ -2470,10 +2483,21 @@ type ClientCredentialsWorkloadConfig = WorkloadConfigBase & {
2470
2483
  */
2471
2484
  clientId: string;
2472
2485
  /**
2473
- * OAuth2 client secret
2474
- * REQUIRED for Client Credentials mode
2486
+ * OAuth2 client secret. Omit it to authenticate with a federated token instead
2487
+ * (see `federatedTokenFile`). A client secret wins when both are present.
2475
2488
  */
2476
- clientSecret: string;
2489
+ clientSecret?: string;
2490
+ /**
2491
+ * Path to a projected federated token (e.g. AKS Workload Identity), sent as a jwt-bearer
2492
+ * `client_assertion` in place of `client_secret`. Defaults to `AZURE_FEDERATED_TOKEN_FILE`.
2493
+ * Read on every acquisition because the platform rotates it.
2494
+ */
2495
+ federatedTokenFile?: string;
2496
+ /**
2497
+ * `managed_identity`: get the token from the platform's managed identity endpoint instead of an
2498
+ * IdP token URL. `clientId` is the managed identity's client ID; `scope` names the audience.
2499
+ */
2500
+ authMethod?: "managed_identity";
2477
2501
  };
2478
2502
  /**
2479
2503
  * Server-Only Workload Configuration
@@ -2507,7 +2531,7 @@ type ServerOnlyWorkloadConfig = WorkloadConfigBase & {
2507
2531
  * detected based on which fields are present:
2508
2532
  *
2509
2533
  * - **JWT Bearer Grant**: Requires `workload_id` + `private_key`
2510
- * - **Client Credentials**: Requires `client_id` + `client_secret`
2534
+ * - **Client Credentials**: Requires `client_id` + `client_secret`, a federated token file, or `authMethod: "managed_identity"`
2511
2535
  * - **Server-Only**: Only `jwks_uri` (and optionally `issuer`) for token validation
2512
2536
  *
2513
2537
  * The developer uses the same API regardless of mode - the library handles the details.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{J,je,d,A,I,v,o,j,c,Ne,Y,f,e,g,x,X,le,Ee,Le,Pe,N,L,T,K,Z,q,n,p,Ke,W,qe,We,Ve,ee,te,V,ne,me,fe,m,z,Ue,B,P,U,G,ze,_,_e,Be,Ge,O,ge,ye,he,Se,ke,be,Ce,Te,we,Re,se,Fe,oe,ie,y,s,He,D,Ae,Ie,i,ae,Je,Ye,r,w,h,Xe,Ze,Oe,F,a,l,t,ce,Qe,De,et,R,S,tt,nt,H,rt,k,M,ve,xe,st,u,b,C,it,at,ue,de}from"./shared/core-knezf9yx.js";var Mt="0.0.24-beta.20261006.21";class ft extends Error{constructor(E,Q){super(E,Q.cause!==void 0?{cause:Q.cause}:void 0);this.name="ConfigSourceError",this.kind=Q.kind,this.recoverable=Q.recoverable,this.code=Q.code,this.status=Q.status,this.path=Q.path,this.sourceType=Q.sourceType,Object.setPrototypeOf(this,ft.prototype)}}function Lt(E){return E instanceof ft}var Nt=["sessionStore","userStore","customerStore","accessStore","tokenStore","magicLinkStore","store"];function Rt(E){if(E===null||typeof E!=="object")return E;let Q={};for(let[re,pe]of Object.entries(E)){if(Nt.includes(re)||re==="validators"||re==="setStores")continue;Q[re]=pe!==null&&typeof pe==="object"&&!Array.isArray(pe)&&Object.getPrototypeOf(pe)===Object.prototype?Rt(pe):pe}return Q}function $t(E){return Rt(E)}function yt(E,Q){if(!E||typeof E!=="object"||Array.isArray(E))throw Error(`${Q} must be an object.`);return E}function ut(E,Q){if(E===void 0)return;if(typeof E!=="string"||E.length===0||!Number.isFinite(Date.parse(E)))throw Error(`${Q} must be a valid timestamp string.`);return E}function Et(E,Q,re){if(!Array.isArray(E)||!re.allowEmpty&&E.length===0)throw Error(`${Q} keys must be ${re.allowEmpty?"an":"a non-empty"} array.`);let pe=new Set;return E.map(($e,Me)=>{let ot=yt($e,`${Q} keys[${Me}]`);if(typeof ot.id!=="string"||ot.id.length===0)throw Error(`${Q} keys[${Me}].id must be a non-empty string.`);if(pe.has(ot.id))throw Error(`${Q} contains duplicate key id "${ot.id}".`);if(pe.add(ot.id),!["pending","active","deprecated","rotated","revoked"].includes(String(ot.state)))throw Error(`${Q} keys[${Me}].state is invalid.`);if(ot.value!==void 0&&(typeof ot.value!=="string"||ot.value.length===0))throw Error(`${Q} keys[${Me}].value must be a non-empty string when present.`);let ct=ot.meta===void 0?void 0:yt(ot.meta,`${Q} keys[${Me}].meta`);return{id:ot.id,state:ot.state,...ot.value===void 0?{}:{value:ot.value},...ot.notBefore===void 0?{}:{notBefore:ut(ot.notBefore,`${Q} keys[${Me}].notBefore`)},...ot.notAfter===void 0?{}:{notAfter:ut(ot.notAfter,`${Q} keys[${Me}].notAfter`)},...ot.createdAt===void 0?{}:{createdAt:ut(ot.createdAt,`${Q} keys[${Me}].createdAt`)},...ot.activatedAt===void 0?{}:{activatedAt:ut(ot.activatedAt,`${Q} keys[${Me}].activatedAt`)},...ot.deprecatedAt===void 0?{}:{deprecatedAt:ut(ot.deprecatedAt,`${Q} keys[${Me}].deprecatedAt`)},...ot.rotatedAt===void 0?{}:{rotatedAt:ut(ot.rotatedAt,`${Q} keys[${Me}].rotatedAt`)},...ot.revokedAt===void 0?{}:{revokedAt:ut(ot.revokedAt,`${Q} keys[${Me}].revokedAt`)},...ct?{meta:{...ct}}:{}}})}function Wt(E,Q,re){if(E===void 0)return;if(!Array.isArray(E))throw Error(`${re} slots must be an array.`);let pe=new Set,$e=E.map((Me,ot)=>{if(Me===null)return null;if(typeof Me!=="string"||Me.length===0)throw Error(`${re} slots[${ot}] must be a non-empty key id or null.`);if(pe.has(Me))throw Error(`${re} slots contain duplicate key id "${Me}".`);pe.add(Me);let ct=Q.find((pt)=>pt.id===Me);if(!ct)throw Error(`${re} slot key "${Me}" is not present in keys.`);if(ct.state!=="active")throw Error(`${re} slot key "${Me}" must have state "active".`);if(!ct.value)throw Error(`${re} slot key "${Me}" must include a value.`);return Me});if(Q.length===0&&$e.some((Me)=>Me!==null))throw Error(`${re} slots must be omitted or all-null when keys is empty.`);return $e}function Ut(E){let re=yt(E,"KMS pool");if(re.kind!=="kms")throw Error('KMS pool kind must be "kms".');let pe=Et(re.keys,"KMS pool",{allowEmpty:!0}),$e=Wt(re.slots,pe,"KMS pool");return $e?{kind:"kms",slots:$e,keys:pe}:{kind:"kms",keys:pe}}function Ft(E){let re=yt(E,"KMS pool control document");if(re.kind!=="kms")throw Error('KMS pool control document kind must be "kms".');return{kind:"kms",keys:Et(re.keys,"KMS pool control document",{allowEmpty:!0})}}var qt={trace:"TRACE",debug:"DEBUG",info:"INFO ",warn:"WARN ",error:"ERROR"};function ht(E){if(typeof E==="string")return E;try{return JSON.stringify(E)??String(E)}catch{return String(E)}}function St(E){let Q=ht(E);return/^[A-Za-z0-9_./:@+|-]+$/.test(Q)?Q:JSON.stringify(Q)}function zt(E){return ht(E).replaceAll("\r","\\r").replaceAll(`
1
+ import{J,je,d,A,I,v,o,j,c,Ne,Y,f,e,g,x,X,le,Ee,Le,Pe,N,L,T,K,Z,q,n,p,Ke,W,qe,We,Ve,ee,te,V,ne,me,fe,m,z,Ue,B,P,U,G,ze,_,_e,Be,Ge,O,ge,ye,he,Se,ke,be,Ce,Te,we,Re,se,Fe,oe,ie,y,s,He,D,Ae,Ie,i,ae,Je,Ye,r,w,h,Xe,Ze,Oe,F,a,l,t,ce,Qe,De,et,R,S,tt,nt,H,rt,k,M,ve,xe,st,u,b,C,it,at,ue,de}from"./shared/core-knezf9yx.js";var Mt="0.0.24-beta.20261006.22";class ft extends Error{constructor(E,Q){super(E,Q.cause!==void 0?{cause:Q.cause}:void 0);this.name="ConfigSourceError",this.kind=Q.kind,this.recoverable=Q.recoverable,this.code=Q.code,this.status=Q.status,this.path=Q.path,this.sourceType=Q.sourceType,Object.setPrototypeOf(this,ft.prototype)}}function Lt(E){return E instanceof ft}var Nt=["sessionStore","userStore","customerStore","accessStore","tokenStore","magicLinkStore","store"];function Rt(E){if(E===null||typeof E!=="object")return E;let Q={};for(let[re,pe]of Object.entries(E)){if(Nt.includes(re)||re==="validators"||re==="setStores")continue;Q[re]=pe!==null&&typeof pe==="object"&&!Array.isArray(pe)&&Object.getPrototypeOf(pe)===Object.prototype?Rt(pe):pe}return Q}function $t(E){return Rt(E)}function yt(E,Q){if(!E||typeof E!=="object"||Array.isArray(E))throw Error(`${Q} must be an object.`);return E}function ut(E,Q){if(E===void 0)return;if(typeof E!=="string"||E.length===0||!Number.isFinite(Date.parse(E)))throw Error(`${Q} must be a valid timestamp string.`);return E}function Et(E,Q,re){if(!Array.isArray(E)||!re.allowEmpty&&E.length===0)throw Error(`${Q} keys must be ${re.allowEmpty?"an":"a non-empty"} array.`);let pe=new Set;return E.map(($e,Me)=>{let ot=yt($e,`${Q} keys[${Me}]`);if(typeof ot.id!=="string"||ot.id.length===0)throw Error(`${Q} keys[${Me}].id must be a non-empty string.`);if(pe.has(ot.id))throw Error(`${Q} contains duplicate key id "${ot.id}".`);if(pe.add(ot.id),!["pending","active","deprecated","rotated","revoked"].includes(String(ot.state)))throw Error(`${Q} keys[${Me}].state is invalid.`);if(ot.value!==void 0&&(typeof ot.value!=="string"||ot.value.length===0))throw Error(`${Q} keys[${Me}].value must be a non-empty string when present.`);let ct=ot.meta===void 0?void 0:yt(ot.meta,`${Q} keys[${Me}].meta`);return{id:ot.id,state:ot.state,...ot.value===void 0?{}:{value:ot.value},...ot.notBefore===void 0?{}:{notBefore:ut(ot.notBefore,`${Q} keys[${Me}].notBefore`)},...ot.notAfter===void 0?{}:{notAfter:ut(ot.notAfter,`${Q} keys[${Me}].notAfter`)},...ot.createdAt===void 0?{}:{createdAt:ut(ot.createdAt,`${Q} keys[${Me}].createdAt`)},...ot.activatedAt===void 0?{}:{activatedAt:ut(ot.activatedAt,`${Q} keys[${Me}].activatedAt`)},...ot.deprecatedAt===void 0?{}:{deprecatedAt:ut(ot.deprecatedAt,`${Q} keys[${Me}].deprecatedAt`)},...ot.rotatedAt===void 0?{}:{rotatedAt:ut(ot.rotatedAt,`${Q} keys[${Me}].rotatedAt`)},...ot.revokedAt===void 0?{}:{revokedAt:ut(ot.revokedAt,`${Q} keys[${Me}].revokedAt`)},...ct?{meta:{...ct}}:{}}})}function Wt(E,Q,re){if(E===void 0)return;if(!Array.isArray(E))throw Error(`${re} slots must be an array.`);let pe=new Set,$e=E.map((Me,ot)=>{if(Me===null)return null;if(typeof Me!=="string"||Me.length===0)throw Error(`${re} slots[${ot}] must be a non-empty key id or null.`);if(pe.has(Me))throw Error(`${re} slots contain duplicate key id "${Me}".`);pe.add(Me);let ct=Q.find((pt)=>pt.id===Me);if(!ct)throw Error(`${re} slot key "${Me}" is not present in keys.`);if(ct.state!=="active")throw Error(`${re} slot key "${Me}" must have state "active".`);if(!ct.value)throw Error(`${re} slot key "${Me}" must include a value.`);return Me});if(Q.length===0&&$e.some((Me)=>Me!==null))throw Error(`${re} slots must be omitted or all-null when keys is empty.`);return $e}function Ut(E){let re=yt(E,"KMS pool");if(re.kind!=="kms")throw Error('KMS pool kind must be "kms".');let pe=Et(re.keys,"KMS pool",{allowEmpty:!0}),$e=Wt(re.slots,pe,"KMS pool");return $e?{kind:"kms",slots:$e,keys:pe}:{kind:"kms",keys:pe}}function Ft(E){let re=yt(E,"KMS pool control document");if(re.kind!=="kms")throw Error('KMS pool control document kind must be "kms".');return{kind:"kms",keys:Et(re.keys,"KMS pool control document",{allowEmpty:!0})}}var qt={trace:"TRACE",debug:"DEBUG",info:"INFO ",warn:"WARN ",error:"ERROR"};function ht(E){if(typeof E==="string")return E;try{return JSON.stringify(E)??String(E)}catch{return String(E)}}function St(E){let Q=ht(E);return/^[A-Za-z0-9_./:@+|-]+$/.test(Q)?Q:JSON.stringify(Q)}function zt(E){return ht(E).replaceAll("\r","\\r").replaceAll(`
2
2
  `,"\\n")}function At(E,Q,re){if(re==null)return;if(re instanceof Error){if(E.push(`${Q}.name=${St(re.name)}`),E.push(`${Q}.message=${St(re.message)}`),re.stack)E.push(`${Q}.stack=${St(re.stack)}`);return}E.push(`${Q}=${St(re)}`)}function dt(E,Q,re=[],pe=new Date){let $e=zt(Q instanceof Error?Q.message:Q??""),Me=[];for(let[ot,ct]of re.entries()){if(ct&&typeof ct==="object"&&!Array.isArray(ct)&&!(ct instanceof Error)&&Object.getPrototypeOf(ct)===Object.prototype){for(let[pt,lt]of Object.entries(ct))At(Me,pt,lt);continue}At(Me,`param.${ot}`,ct)}return[pe.toISOString(),qt[E],$e,...Me].filter(Boolean).join(" ")}var It={trace:()=>{},debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},Vt=It,jt={trace:()=>{},debug:console.debug,info:console.info,warn:console.warn,error:console.error},Bt={trace:()=>{},debug:()=>{},info:console.info,warn:console.warn,error:console.error},Gt={trace:()=>{},debug:()=>{},info:()=>{},warn:console.warn,error:console.error},Ht={trace:()=>{},debug:(E,...Q)=>globalThis.console.debug(dt("debug",E,Q)),info:(E,...Q)=>globalThis.console.info(dt("info",E,Q)),warn:(E,...Q)=>globalThis.console.warn(dt("warn",E,Q)),error:(E,...Q)=>globalThis.console.error(dt("error",E,Q))};function Yt(E,Q){if(typeof Q!=="number"||Q<=0)return E;return new Promise((re,pe)=>{let $e=setTimeout(()=>{pe(Error(`Authz catalog entry did not become ready within ${Q}ms`))},Q);E.then(()=>{clearTimeout($e),re()},(Me)=>{clearTimeout($e),pe(Me)})})}function Jt(E,Q){let re=!1,pe,$e=Q.then(()=>{re=!0},(ot)=>{re=!1,pe=ot}),Me=E;return Object.defineProperty(Me,"ready",{enumerable:!1,configurable:!0,value:(ot)=>Yt($e.then(()=>{if(!re)throw pe}),ot)}),Object.defineProperty(Me,"isReady",{enumerable:!1,configurable:!0,value:()=>re}),Me}var Ct=Object.freeze({jsonc:s,env:"text/x-dotenv",text:"text/plain",binary:Ie,yaml:"application/yaml",toml:"application/toml",xml:Ae});function kt(E){if(!E.id.trim())throw Error("defineSecretType: id is required");let Q=E.mimeType?.trim()||Ct[E.format],re=Object.freeze({id:E.id,...E.label?{label:E.label}:{},format:E.format,mimeType:Q,...E.schemaUrl?{schemaUrl:E.schemaUrl}:{},typeId:E.id});return Object.freeze({id:E.id,...E.label?{label:E.label}:{},format:E.format,mimeType:Q,...E.schemaUrl?{schemaUrl:E.schemaUrl}:{},...E.schema?{schema:E.schema}:{},toRegistryEntry:()=>re})}function Xt(E="jsonc"){return{format:E,mimeType:Ct[E],typeId:E}}class bt extends Error{constructor(E,Q){super(`Secret content type mismatch: expected "${E.mimeType}" (${E.format}) but received "${Q.mimeType}" (${Q.format})`);this.name="SecretContentTypeMismatchError",this.expected=E,this.received=Q}}var Zt=kt({id:"ionite-remote-config",label:"ionite RemoteConfig",format:"jsonc",mimeType:"application/vnd.ionite.remote-config+json",schemaUrl:"https://ionite.com/schemas/remote-config.json"});var Pt={beforeTenantSegments:["ui"]},_t={beforeTenantSegments:["api"]};function xt(E){return(E??[]).map((Q)=>Q.trim()).filter(Boolean)}function Ot(E){let Q=E.trim();if(!Q)return"/";let re=Q.replace(/\\/g,"/").replace(/\/+/g,"/");return re.startsWith("/")?re:`/${re}`}function vt(E){return Ot(E).split("/").filter(Boolean)}function gt(E){return{beforeTenantSegments:xt(E?.beforeTenantSegments),afterTenantSegments:xt(E?.afterTenantSegments)}}function wt(E){if(E?.type==="host")return{type:"host",baseDomain:Tt(E.baseDomain)};if(E?.type==="selector")return E;return{type:"path",ui:gt(E?.ui??Pt),api:gt(E?.api??_t)}}function Tt(E){let Q=E.trim().replace(/^\.+|\.+$/g,"").toLowerCase();if(!Q)throw Error('Host tenant routing requires a non-empty baseDomain such as "app.example.com".');return Q}function Qt(E,Q){let re=E.trim().replace(/\.$/,"").toLowerCase(),pe=Tt(Q);if(!re.endsWith(`.${pe}`))return null;let $e=re.slice(0,-(pe.length+1));if(!$e||$e.includes("."))return null;return{id:$e}}function eo(E,Q){let re=gt(Q),pe=re.beforeTenantSegments??[],$e=re.afterTenantSegments??[],Me=vt(E),ot=pe.length+1+$e.length;if(Me.length<ot)return null;for(let mt=0;mt<pe.length;mt++)if(Me[mt]!==pe[mt])return null;let ct=pe.length,pt=Me[ct];if(!pt)return null;for(let mt=0;mt<$e.length;mt++)if(Me[ct+1+mt]!==$e[mt])return null;let lt=Me.slice(ct+1+$e.length);return{id:decodeURIComponent(pt),restSegments:lt,restPath:lt.length>0?`/${lt.join("/")}`:"/"}}function Kt(E,Q="/",re){let pe=gt(re),$e=pe.beforeTenantSegments??[],Me=pe.afterTenantSegments??[],ot=vt(Q),ct=[...$e,encodeURIComponent(E),...Me,...ot];return ct.length>0?`/${ct.join("/")}`:"/"}function to(E,Q="/",re,pe="ui"){let $e=wt(re);if($e.type==="host"||$e.type==="selector")return Ot(Q);return Kt(E,Q,$e[pe])}function oo(E){return{"~standard":{version:1,vendor:E,validate:(Q)=>{if(typeof Q!=="object"||Q===null)return{issues:[{message:"Expected an object"}]};let re=Q,pe=[],$e={...re},Me=["iss","sub"];for(let pt of Me)if(pt in re){if(typeof re[pt]!=="string")pe.push({message:`${pt} must be a string`,path:[pt]})}else pe.push({message:`${pt} is required`,path:[pt]});if("aud"in re&&re.aud!==void 0){let pt=re.aud;if(typeof pt!=="string"&&!Array.isArray(pt))pe.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(pt)&&!pt.every((lt)=>typeof lt==="string"))pe.push({message:"aud array must contain only strings",path:["aud"]})}let ot=["jti","scope"];for(let pt of ot)if(pt in re&&re[pt]!==void 0){if(typeof re[pt]!=="string")pe.push({message:`${pt} must be a string`,path:[pt]})}let ct=["exp","iat"];for(let pt of ct)if(pt in re){if(typeof re[pt]!=="number")pe.push({message:`${pt} must be a number`,path:[pt]})}else pe.push({message:`${pt} is required`,path:[pt]});if(pe.length>0)return{issues:pe};return{value:$e}}}}}function ro(E){return{"~standard":{version:1,vendor:E,validate:(Q)=>{if(typeof Q!=="object"||Q===null)return{issues:[{message:"Expected an object"}]};let re=Q,pe=[],$e={};if("access_token"in re)if(typeof re.access_token==="string")$e.access_token=re.access_token;else pe.push({message:"access_token must be a string",path:["access_token"]});else pe.push({message:"access_token is required",path:["access_token"]});if("token_type"in re)if(typeof re.token_type==="string")$e.token_type=re.token_type;else pe.push({message:"token_type must be a string",path:["token_type"]});else pe.push({message:"token_type is required",path:["token_type"]});if("scope"in re)if(typeof re.scope==="string"||re.scope===void 0)$e.scope=re.scope;else pe.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in re)if(typeof re.refresh_token==="string"||re.refresh_token===void 0)$e.refresh_token=re.refresh_token;else pe.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in re)if(typeof re.expires==="string"||re.expires===void 0)$e.expires=re.expires;else pe.push({message:"expires must be a string",path:["expires"]});if("expires_in"in re)if(typeof re.expires_in==="number"||re.expires_in===void 0)$e.expires_in=re.expires_in;else pe.push({message:"expires_in must be a number",path:["expires_in"]});if(pe.length>0)return{issues:pe};return{value:$e}}}}}function no(E){let Q=new Uint8Array(E);return crypto.getRandomValues(Q),Q}function so(E){let Q="",re=no(E);for(let pe=0;pe<E;pe++){let $e=re[pe]%32;Q+="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt($e)}return Q}function io(E,Q){let re="";for(let pe=Q;pe>0;pe--){let $e=E%32;re="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt($e)+re,E=Math.floor(E/32)}return re}function ao(E){let Q=Date.now(),re=io(Q,10),pe=so(16);return`${E??""}${re}${pe}`}export{i as ACCEPT_JSON,Ye as ACCEPT_OCTET_STREAM,ae as ACCEPT_SCIM,Je as ACCEPT_XML,le as AssignmentPolicyError,Y as CANONICAL_RISK_LEVELS,h as CONTENT_TYPE_FORM,r as CONTENT_TYPE_JSON,Ze as CONTENT_TYPE_OCTET_STREAM,w as CONTENT_TYPE_SCIM,Xe as CONTENT_TYPE_XML,ft as ConfigSourceError,We as DEFAULT_DISCOVERED_COOKIE_MAX,Ve as DEFAULT_DISCOVERED_COOKIE_TTL_SECONDS,qe as DEFAULT_DISPLAY_COOKIE_MAX,f as DEFAULT_RISK_LEVEL,Ct as DEFAULT_SECRET_MIME_TYPES,_t as DEFAULT_TENANT_API_NAMESPACE,Pt as DEFAULT_TENANT_UI_NAMESPACE,ee as DISCOVERED_COOKIE_PREFIX,Ke as DISPLAY_COOKIE_SUFFIX,W as DISPLAY_COOKIE_VERSION,ze as ECID_SCHEME,_ as EcidFormatError,D as FORM_MEDIA_TYPE,e as ION_AUTHZ_GROUP_SCHEMA,we as ION_AUTHZ_OAA_SYNC,Ce as ION_CAPABILITIEZ_READ,Te as ION_CIAM_MAGIC_LINK_CREATE,Fe as ION_ENDPOINT_PERMISSIONS,be as ION_IAM_ACCESS_REQUESTS_WRITE,ke as ION_IAM_CUSTOMERS_WRITE,he as ION_IAM_GROUPS_WRITE,ge as ION_IAM_READ,ye as ION_IAM_USERS_WRITE,Se as ION_IAM_WORKLOADS_WRITE,C as ION_SCIM_CUSTOMER_SCHEMA,u as ION_SCIM_USER_EXTENSION_URN,b as ION_SCIM_WORKLOAD_SCHEMA,se as ION_SDK_PERMISSIONS,Re as ION_TENANT_MANAGE,ve as IoniteError,s as JSON_MEDIA_TYPE,I as KNOWN_BASE_CUSTOMER_KEYS,A as KNOWN_BASE_USER_KEYS,d as KNOWN_ENTITLEMENT_KEYS,v as KNOWN_WORKLOAD_KEYS,Ie as OCTET_STREAM_MEDIA_TYPE,g as PLATFORM_ASSIGNABLE_SUBJECT_TYPES,He as SCIM_MEDIA_TYPE,bt as SecretContentTypeMismatchError,k as StoreConflictError,Ae as XML_MEDIA_TYPE,n as accessRefId,p as accessRootId,O as assertEcid,X as assertRequiredSubjectType,x as assertValidSubjectTypeScoping,Kt as buildTenantPath,to as buildTenantUrl,L as catalogEntityStore,H as claimsToUser,P as compareDisplayExpiryDesc,je as configTrustedClientGrants,o as customAttributes,de as customerResourceSchema,jt as debugLogger,Ue as decodeDisplayCookie,rt as decodeUser,S as deepEqualPlain,me as defaultDisplayUser,Vt as defaultLogger,Xt as defaultSecretContentType,Pe as defineCatalog,kt as defineSecretType,Z as deprecateRetiredCodeCatalogRows,G as discoveredProfileCookieName,z as encodeDisplayCookie,Be as formatEcid,dt as formatLogLine,ao as generateULID,N as getCodeCatalogEntity,at as groupResourceSchema,y as idTokenClaimsSchema,Bt as infoLogger,Ee as isCodeCatalog,xe as isConfigLocator,Lt as isConfigSourceError,_e as isEcid,Oe as isJsonResponse,M as isStoreConflictError,oo as jwtAssertionClaimsSchema,j as list,c as listGenerator,Qt as matchTenantHost,eo as matchTenantPath,Ne as matchesListFilter,K as materializeCodeCatalogEntity,T as mergeCodeCatalogEntity,Qe as mergeConfig,t as must,Tt as normalizeTenantBaseDomain,gt as normalizeTenantPathNamespace,wt as normalizeTenantRoutingStrategy,oe as oidcCallbackSchema,Ge as parseEcid,et as parseJsonc,Ft as parseKmsPoolControlDocument,Ut as parseKmsPoolDocument,Ht as prettyLogger,U as profileCookieName,m as projectDisplayUser,B as readDisplayCookies,a as readJsonResponse,Jt as readyCatalogEntry,Zt as remoteConfigSecretType,V as resolveDiscoveredCookieMax,ne as resolveDiscoveredCookieTtlSeconds,te as resolveDisplayCookieMax,fe as sanitizeDisplayUser,$t as serializeConfig,It as silentLogger,tt as stableConfigHash,De as stripJsonComments,st as tmIntegrationState,Le as toCodeCatalog,ie as tokenResponseSchema,R as trimTrailingSlash,J as trustedClientPermissionsForPrincipal,F as unexpectedBodySummary,q as unionCatalogRead,it as userSchema,ce as validationFailureResponse,Mt as version,nt as waitOn,Gt as warnLogger,l as withValidate,ue as workloadResourceSchema,ro as workloadTokenResponseSchema};
package/dist/server.d.ts CHANGED
@@ -1415,6 +1415,19 @@ type CIAMProviderConfig = {
1415
1415
  claimsAsEntitlements?: ClaimsAsEntitlements;
1416
1416
  /** ConfigSource-only IdP assignment workflow used when IAM assignment is `'idp'`. */
1417
1417
  accessRequests?: AccessRequestsDestination;
1418
+ /**
1419
+ * Microsoft only. Which Entra tenants may sign in when the provider uses a
1420
+ * multi-tenant authority (`/common`, `/organizations`, `/consumers`). Entra mints
1421
+ * tenant-scoped issuers (`https://login.microsoftonline.com/{tid}/v2.0`), so no
1422
+ * single `authority` can be compared by strict equality; this constrains the
1423
+ * accepted `tid` instead.
1424
+ *
1425
+ * `'any'` (default) accepts any work/school tenant and personal accounts,
1426
+ * `'consumers'` accepts only personal Microsoft accounts, and an array accepts
1427
+ * only the listed tenant GUIDs. Ignored when `authority` names a single tenant —
1428
+ * that keeps the strict-equality check.
1429
+ */
1430
+ allowedTenants?: "any" | "consumers" | string[];
1418
1431
  };
1419
1432
  /** Sanitized provider entry returned by the discovery endpoint for the UI. */
1420
1433
  type CIAMProviderDescriptor = {
@@ -1441,6 +1454,8 @@ type CiamClaimCandidate = {
1441
1454
  type CIAMProviderFlow = "id_token" | "userinfo";
1442
1455
  type CIAMProviderPreset = {
1443
1456
  flow: CIAMProviderFlow;
1457
+ /** Default issuer/authority when the config omits one. */
1458
+ authority?: string;
1444
1459
  authorizationUrl?: string;
1445
1460
  tokenUrl?: string;
1446
1461
  jwksUri?: string;
@@ -1459,6 +1474,8 @@ type ResolvedCiamProvider = {
1459
1474
  name: string;
1460
1475
  type: CIAMProviderType;
1461
1476
  flow: CIAMProviderFlow;
1477
+ /** Effective issuer/authority (config override, else preset default). */
1478
+ authority?: string;
1462
1479
  authorizationUrl?: string;
1463
1480
  tokenUrl?: string;
1464
1481
  jwksUri?: string;
@@ -1827,7 +1844,7 @@ type WorkloadClientDescription = {
1827
1844
  idpTokenUrl?: string;
1828
1845
  scope?: string;
1829
1846
  audience?: string;
1830
- authMethod: "client_secret" | "private_key_jwt" | "server_only";
1847
+ authMethod: "client_secret" | "federated_token" | "managed_identity" | "private_key_jwt" | "server_only";
1831
1848
  };
1832
1849
  type WorkloadDescription = ModuleDescriptionBase<"workload"> & {
1833
1850
  incoming: {
@@ -2249,10 +2266,21 @@ type ClientCredentialsWorkloadConfig = WorkloadConfigBase & {
2249
2266
  */
2250
2267
  clientId: string;
2251
2268
  /**
2252
- * OAuth2 client secret
2253
- * REQUIRED for Client Credentials mode
2269
+ * OAuth2 client secret. Omit it to authenticate with a federated token instead
2270
+ * (see `federatedTokenFile`). A client secret wins when both are present.
2254
2271
  */
2255
- clientSecret: string;
2272
+ clientSecret?: string;
2273
+ /**
2274
+ * Path to a projected federated token (e.g. AKS Workload Identity), sent as a jwt-bearer
2275
+ * `client_assertion` in place of `client_secret`. Defaults to `AZURE_FEDERATED_TOKEN_FILE`.
2276
+ * Read on every acquisition because the platform rotates it.
2277
+ */
2278
+ federatedTokenFile?: string;
2279
+ /**
2280
+ * `managed_identity`: get the token from the platform's managed identity endpoint instead of an
2281
+ * IdP token URL. `clientId` is the managed identity's client ID; `scope` names the audience.
2282
+ */
2283
+ authMethod?: "managed_identity";
2256
2284
  };
2257
2285
  /**
2258
2286
  * Server-Only Workload Configuration
@@ -2286,7 +2314,7 @@ type ServerOnlyWorkloadConfig = WorkloadConfigBase & {
2286
2314
  * detected based on which fields are present:
2287
2315
  *
2288
2316
  * - **JWT Bearer Grant**: Requires `workload_id` + `private_key`
2289
- * - **Client Credentials**: Requires `client_id` + `client_secret`
2317
+ * - **Client Credentials**: Requires `client_id` + `client_secret`, a federated token file, or `authMethod: "managed_identity"`
2290
2318
  * - **Server-Only**: Only `jwks_uri` (and optionally `issuer`) for token validation
2291
2319
  *
2292
2320
  * The developer uses the same API regardless of mode - the library handles the details.
@@ -6265,10 +6293,69 @@ declare function exchangeAuthorizationCode(options: ExchangeCodeOptions): Promis
6265
6293
  * so `https://idp/realm` and `https://idp/realm/` compare equal.
6266
6294
  */
6267
6295
  declare function normalizeOidcIssuer(iss: string): string;
6296
+ /**
6297
+ * Microsoft Entra ID issues TENANT-SCOPED issuers even when the app is configured
6298
+ * against a `/common` (or `/organizations`, `/consumers`) authority: the ID token's
6299
+ * `iss` is always `https://login.microsoftonline.com/{tid}/v2.0`, where `{tid}` is
6300
+ * the GUID of the home tenant that authenticated the user. Personal Microsoft
6301
+ * accounts (MSA) use the fixed consumers tenant GUID below.
6302
+ *
6303
+ * So for a multi-tenant or consumer app there is no single `authority` string that
6304
+ * can be compared with strict equality — hence {@link matchesMicrosoftIssuer},
6305
+ * which validates the issuer's SHAPE and then constrains the `tid` against an
6306
+ * operator allowlist. Single-tenant apps should keep an exact `authority` (e.g.
6307
+ * `https://login.microsoftonline.com/{their-tid}/v2.0`), which still takes the
6308
+ * strict-equality path.
6309
+ */
6310
+ declare const MICROSOFT_CONSUMERS_TENANT_ID = "9188040d-6c67-4c5b-b112-36a304b66dad";
6311
+ /**
6312
+ * Operator constraint on which Entra tenants may sign in, from RemoteConfig
6313
+ * (`allowedTenants`). `'any'` accepts any work/school tenant AND personal accounts;
6314
+ * `'consumers'` accepts only personal Microsoft accounts; an array accepts only the
6315
+ * listed tenant GUIDs (the literal `'consumers'` may appear in the array as an alias
6316
+ * for the MSA tenant). Omitted defaults to `'any'`, matching what a `/common`
6317
+ * authority already means at the authorization endpoint.
6318
+ */
6319
+ type MicrosoftAllowedTenants = "any" | "consumers" | string[];
6320
+ /** True when `authority` is a Microsoft multi-tenant/consumer authority (`/common` et al). */
6321
+ declare function isMicrosoftMultiTenantAuthority(authority: string): boolean;
6322
+ /** Extract the tenant GUID from a well-formed Entra v2 issuer, or undefined. */
6323
+ declare function microsoftIssuerTenantId(iss: string): string | undefined;
6324
+ /**
6325
+ * Validate a Microsoft Entra ID token issuer for a multi-tenant/consumer app.
6326
+ *
6327
+ * Fails closed in two stages: the issuer must match the exact Entra v2 issuer shape
6328
+ * (so an attacker-controlled host can never satisfy it), and the embedded tenant GUID
6329
+ * must be permitted by `allowedTenants`. When the token also carries a `tid` claim it
6330
+ * MUST agree with the tenant in `iss` — Entra always sets both, and a disagreement
6331
+ * means the token was not minted by the tenant it claims.
6332
+ */
6333
+ declare function matchesMicrosoftIssuer(options: {
6334
+ iss: string;
6335
+ /** The `tid` claim, when present — cross-checked against the issuer's tenant. */
6336
+ tid?: unknown;
6337
+ allowedTenants?: MicrosoftAllowedTenants;
6338
+ }): boolean;
6339
+ /**
6340
+ * How the `iss` claim is validated. `exact` (the default) requires `iss` to equal
6341
+ * the configured issuer after normalization — the correct behaviour for every
6342
+ * provider with a fixed issuer. `microsoft-tenant` additionally accepts a
6343
+ * tenant-scoped Entra issuer (`https://login.microsoftonline.com/{tid}/v2.0`)
6344
+ * constrained by `allowedTenants`, which is the only way a `/common` authority can
6345
+ * verify at all (see {@link matchesMicrosoftIssuer}).
6346
+ */
6347
+ type IdTokenIssuerPolicy = {
6348
+ mode: "exact";
6349
+ } | {
6350
+ mode: "microsoft-tenant";
6351
+ allowedTenants?: MicrosoftAllowedTenants;
6352
+ };
6268
6353
  type AssertTrustedIdTokenClaimsOptions = {
6269
6354
  claims: Record<string, unknown>;
6270
6355
  /** Expected issuer (provider `authority`). Required. */
6271
6356
  issuer: string;
6357
+ /** Issuer-matching policy. Defaults to strict equality. */
6358
+ issuerPolicy?: IdTokenIssuerPolicy;
6272
6359
  /** Expected audience (provider `clientId`). Required. */
6273
6360
  audience: string;
6274
6361
  /** Current time in epoch seconds (defaults to now). */
@@ -6297,6 +6384,8 @@ type VerifyIdTokenOptions = {
6297
6384
  jwksUri: string;
6298
6385
  /** Expected issuer (provider `authority`). Required; a mismatch throws. */
6299
6386
  issuer: string;
6387
+ /** Issuer-matching policy. Defaults to strict equality. */
6388
+ issuerPolicy?: IdTokenIssuerPolicy;
6300
6389
  /** Expected audience (provider `clientId`). Required; a mismatch throws. */
6301
6390
  audience: string;
6302
6391
  /** Clock-skew allowance for `exp` in seconds (default 60). */
@@ -6477,4 +6566,4 @@ type TenantAccessLoginUrlOptions = {
6477
6566
  tenantIonBasePath?: (tenantId: string) => string;
6478
6567
  };
6479
6568
  declare function tenantAccessLoginUrl(tenantId: string, options: TenantAccessLoginUrlOptions): string;
6480
- export { AccessRequestCreate, AccessRequestResult, AccessRequestsDestination, AfterLoginContext, AfterLoginHook, AfterLogoutContext, AfterLogoutHook, AssertTrustedIdTokenClaimsOptions, BeforeLoginContext, BeforeLoginHook, BeforeLogoutContext, BeforeLogoutHook, CACHE_BOUNDS, CIAM, CIAMConfig, CIAMConfigFromCode, CIAMProviderBranding, CIAMProviderColors, CIAMProviderConfig, CIAMProviderDescriptor, CIAMProviderType, CIAMValidators, CIAM_PROVIDER_PRESETS, CatalogAdjacencyCache, CatalogView, ClaimsAsEntitlements, ClaimsAsEntitlementsDescription, CreateGroupOptions, CreateUserOptions, DeriveClaimsInput, DerivedEntitlement, DiscoveredTenantCookie, DisplayCookieAttributes, DisplayCookieCandidate, DisplayCookieTrim, GroupsInboundHandlerConfig, IAM, IAMAccessRequestsConfig, IAMConfig, IAMDiscoveryConfig, IAMDiscoveryContext, IAMDiscoveryHandlerConfig, IAMGroupsInbound, IAMGroupsOutbound, IAMHandlerConfig, IAMInboundUserContext, IAMInboundUsersConfig, IAMUsersInbound, IAMValidators, InMemoryTenantStore, JWKS, ReconcileStores, RedirectContext, RedirectPolicy, RedirectResult, RedirectRule, RedirectRuleContext, RedirectVerdict, ReferencedDefinitions, ResolveTenantOwnerOptions, ResolveTenantSessionOptions, ResolvedCacheConfig, ResolvedJwksCacheConfig, ResolvedSessionCacheConfig, ResolvedSessionReadCacheConfig, SSO, SSOConfig, SSOHandlerConfig, SSOValidators, ScimAuthenticationScheme, ScimError, ScimListResponse, ScimResourceType, ScimResourceTypeSchemaExtension, ScimResult, ScimSchemaAttributeDefinition, ScimSchemaDefinition, ScimServiceProviderConfig, SessionDiscoveryOptions, SessionResponse, SigningKey, SigningKeyRing, StateCookie, StaticSigningKeyRingDocument, TENANT_OWNER_PERMISSION, TenantAccessDenial, TenantAccessDenialReason, TenantAccessLoginUrlOptions, TenantAccessResult, TenantAccessSession, TenantAccessSessionKind, UsersInboundHandlerConfig, VerifyIdTokenOptions, VerifyLogoutTokenOptions, VerifyUserOptions, allowHosts, allowOrigins, allowRelativePaths, allowSameOrigin, assertSubjectTypeAssignable, assertTrustedIdTokenClaims, baseCustomerToScim, baseUserToScimUser, baseWorkloadToScim, blockDangerousUrls, buildAuthorizationUrl, buildLfvSigningInput, callback, captureRedirect, ciam, clearDiscoveryCache, clearJwksCache, collectReferencedDefinitions, configureJwksCache, decodeUnverifiedJwtPayload, defaultRedirectPolicies, deriveClaimsEntitlements, derivedEntitlementsFor, discoverOidcEndpoints, discoverSessionRecords, discoverSessions, entitlementToScimGroup, exchangeAuthorizationCode, expandRoot, fetchUserInfo, formatDisplayClearCookie, formatDisplaySetCookie, generateAppleClientSecret, generateLfvEd25519KeyPair, getCachedVerificationKey, getCustomer, getDiscoveredSessionUsers, getJwks, getOwnedTenantIds, getProviderPreset, getPublicKeyForKid, getPublicKeyFromJwks, getUser, getVerificationKeyForKid, has, hasAll2 as hasAll, hasAllScope, hasAny2 as hasAny, hasAnyScope, hasGroup2 as hasGroup, hasPermission2 as hasPermission, hasRole2 as hasRole, hasScope, iam, initiateLogin, isRedirectAllowed, listSsoClientIdsFromCookies, normalizeOidcIssuer, orderedEnabledProviders, parseLfvJwks, pkceChallengeFromVerifier, planDiscoveredTenantCookies, planDisplayCookieClear, planDisplayCookieHeaders, reconcileSubjectAccess, rememberDerivedEntitlements, resolveAfterRedirect, resolveCacheConfig, resolveCapturedRedirect, resolveCiamProvider, resolveCustomer, resolveJwkForKid, resolveJwksCacheConfig, resolveProviderBranding, resolveRedirect, resolveSessionCacheConfig, resolveTenantOwner, resolveTenantSession, resolveUser, sameOriginRedirectRules, selectDisplayCookies, sendTenantWebhook, setDiscoveryClock, setJwksClock, setJwksRetry, signCompactJwt, signLfvPayload, sso, staticSigningKeyRing, stringifyLfvJwks, tenantAccessLoginUrl, tenantOwnerEntitlementId, tenantOwnerPermission, tenantResourceId, verifyCompactJwt, verifyIdToken, verifyLfvSignature, verifyLogoutToken, verifyUser, withSetCookies };
6569
+ export { AccessRequestCreate, AccessRequestResult, AccessRequestsDestination, AfterLoginContext, AfterLoginHook, AfterLogoutContext, AfterLogoutHook, AssertTrustedIdTokenClaimsOptions, BeforeLoginContext, BeforeLoginHook, BeforeLogoutContext, BeforeLogoutHook, CACHE_BOUNDS, CIAM, CIAMConfig, CIAMConfigFromCode, CIAMProviderBranding, CIAMProviderColors, CIAMProviderConfig, CIAMProviderDescriptor, CIAMProviderType, CIAMValidators, CIAM_PROVIDER_PRESETS, CatalogAdjacencyCache, CatalogView, ClaimsAsEntitlements, ClaimsAsEntitlementsDescription, CreateGroupOptions, CreateUserOptions, DeriveClaimsInput, DerivedEntitlement, DiscoveredTenantCookie, DisplayCookieAttributes, DisplayCookieCandidate, DisplayCookieTrim, GroupsInboundHandlerConfig, IAM, IAMAccessRequestsConfig, IAMConfig, IAMDiscoveryConfig, IAMDiscoveryContext, IAMDiscoveryHandlerConfig, IAMGroupsInbound, IAMGroupsOutbound, IAMHandlerConfig, IAMInboundUserContext, IAMInboundUsersConfig, IAMUsersInbound, IAMValidators, IdTokenIssuerPolicy, InMemoryTenantStore, JWKS, MICROSOFT_CONSUMERS_TENANT_ID, MicrosoftAllowedTenants, ReconcileStores, RedirectContext, RedirectPolicy, RedirectResult, RedirectRule, RedirectRuleContext, RedirectVerdict, ReferencedDefinitions, ResolveTenantOwnerOptions, ResolveTenantSessionOptions, ResolvedCacheConfig, ResolvedJwksCacheConfig, ResolvedSessionCacheConfig, ResolvedSessionReadCacheConfig, SSO, SSOConfig, SSOHandlerConfig, SSOValidators, ScimAuthenticationScheme, ScimError, ScimListResponse, ScimResourceType, ScimResourceTypeSchemaExtension, ScimResult, ScimSchemaAttributeDefinition, ScimSchemaDefinition, ScimServiceProviderConfig, SessionDiscoveryOptions, SessionResponse, SigningKey, SigningKeyRing, StateCookie, StaticSigningKeyRingDocument, TENANT_OWNER_PERMISSION, TenantAccessDenial, TenantAccessDenialReason, TenantAccessLoginUrlOptions, TenantAccessResult, TenantAccessSession, TenantAccessSessionKind, UsersInboundHandlerConfig, VerifyIdTokenOptions, VerifyLogoutTokenOptions, VerifyUserOptions, allowHosts, allowOrigins, allowRelativePaths, allowSameOrigin, assertSubjectTypeAssignable, assertTrustedIdTokenClaims, baseCustomerToScim, baseUserToScimUser, baseWorkloadToScim, blockDangerousUrls, buildAuthorizationUrl, buildLfvSigningInput, callback, captureRedirect, ciam, clearDiscoveryCache, clearJwksCache, collectReferencedDefinitions, configureJwksCache, decodeUnverifiedJwtPayload, defaultRedirectPolicies, deriveClaimsEntitlements, derivedEntitlementsFor, discoverOidcEndpoints, discoverSessionRecords, discoverSessions, entitlementToScimGroup, exchangeAuthorizationCode, expandRoot, fetchUserInfo, formatDisplayClearCookie, formatDisplaySetCookie, generateAppleClientSecret, generateLfvEd25519KeyPair, getCachedVerificationKey, getCustomer, getDiscoveredSessionUsers, getJwks, getOwnedTenantIds, getProviderPreset, getPublicKeyForKid, getPublicKeyFromJwks, getUser, getVerificationKeyForKid, has, hasAll2 as hasAll, hasAllScope, hasAny2 as hasAny, hasAnyScope, hasGroup2 as hasGroup, hasPermission2 as hasPermission, hasRole2 as hasRole, hasScope, iam, initiateLogin, isMicrosoftMultiTenantAuthority, isRedirectAllowed, listSsoClientIdsFromCookies, matchesMicrosoftIssuer, microsoftIssuerTenantId, normalizeOidcIssuer, orderedEnabledProviders, parseLfvJwks, pkceChallengeFromVerifier, planDiscoveredTenantCookies, planDisplayCookieClear, planDisplayCookieHeaders, reconcileSubjectAccess, rememberDerivedEntitlements, resolveAfterRedirect, resolveCacheConfig, resolveCapturedRedirect, resolveCiamProvider, resolveCustomer, resolveJwkForKid, resolveJwksCacheConfig, resolveProviderBranding, resolveRedirect, resolveSessionCacheConfig, resolveTenantOwner, resolveTenantSession, resolveUser, sameOriginRedirectRules, selectDisplayCookies, sendTenantWebhook, setDiscoveryClock, setJwksClock, setJwksRetry, signCompactJwt, signLfvPayload, sso, staticSigningKeyRing, stringifyLfvJwks, tenantAccessLoginUrl, tenantOwnerEntitlementId, tenantOwnerPermission, tenantResourceId, verifyCompactJwt, verifyIdToken, verifyLfvSignature, verifyLogoutToken, verifyUser, withSetCookies };
package/dist/server.js CHANGED
@@ -1 +1 @@
1
- import{J,d,A,I,v,o,c,Y,f,e,g,x,N,L,K,Z,q,n,p,Q,E,pe,$e,W,ee,te,V,ne,m,z,re,B,P,U,G,O,se,oe,ie,y,s,D,i,ae,r,w,h,F,a,l,t,ce,R,S,H,k,M,Me,ot,u,b,C,ue,de}from"./shared/core-knezf9yx.js";var Vs=new Set(se.map((T)=>T.id));async function bn(T){let _=qs(T.block);if(_.length===0||!T.subjectId)return[];let j=zs(T.claims,T.accessClaims,T.scope),X=T.block.expand===!0,le=X&&T.block.resources===!0,ge=[],he=new Set,ke=(ye)=>{let fe=`${ye.targetType}:${ye.target}:${ye.resource??""}`;if(he.has(fe))return;he.add(fe),ge.push(ye)};for(let ye of _){let fe=Bs(j,ye);for(let ze of fe){let Ye=await Ks(T.catalog,ze);if(!Ye){T.log?.debug("claims entitlement dropped: value is not a catalog id",{"ion.event":"ion.authz.claims.unmatched","ion.module":"authz",claim:ye,value:ze});continue}if(!X||!T.catalog){ke({targetType:Ye,target:ze,claim:ye});continue}let Qe={subject:T.subjectId,subjectType:T.subjectType,targetType:Ye,target:ze,...le?Fs(await Hs(T.catalog,Ye,ze)):{applyToApplication:!0}},ct=await E(Qe,T.catalog),st=Qe.id;for(let _e of ct){if(_e.resource&&!le)continue;ke({targetType:_e.targetType,target:_e.target,..._e.resource?{resource:_e.resource}:{},claim:ye,root:st??_e.rootId})}}}return ge}function Cn(T){if(!T)return;let _=T.split(".");if(_.length!==3||!_[1])return;try{let j=_[1].replace(/-/g,"+").replace(/_/g,"/"),X=j.padEnd(j.length+(4-j.length%4)%4,"="),le=JSON.parse(atob(X));return le&&typeof le==="object"&&!Array.isArray(le)?le:void 0}catch{return}}var tr=new WeakMap;function vn(T,_,j){let X=tr.get(T)??{};X[_]=j??[],tr.set(T,X)}function nr(T,_){return tr.get(T)?.[_]}function qs(T){return T.claims.filter((_)=>typeof _==="string"&&_.length>0)}function zs(T,_,j){let X={...T};if(_){for(let[le,ge]of Object.entries(_))if(X[le]===void 0)X[le]=ge}if(X.scope===void 0&&j)X.scope=j;return X}function Bs(T,_){let j=Gs(T,_);if(typeof j==="string")return _==="scope"||_.endsWith(".scope")?j.split(/\s+/).filter(Boolean):j.length>0?[j]:[];if(Array.isArray(j))return j.filter((X)=>typeof X==="string"&&X.length>0);return[]}function Gs(T,_){let j=T;for(let X of _.split(".")){if(!j||typeof j!=="object"||Array.isArray(j))return;j=j[X]}return j}async function Ks(T,_){if(Vs.has(_))return"permission";if(!T)return;for(let j of["permission","role","group"])if(await Js(T,j,_))return j;return}async function Js(T,_,j){if(Kr(T,_,j))return!0;let le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups;if(!le)return!1;return await le.get(j)!==void 0}function Kr(T,_,j){if(!T.code)return;if(_==="permission")return T.code.permissions.get(j);if(_==="role")return T.code.roles.get(j);return T.code.groups.get(j)}async function Hs(T,_,j){let X=Kr(T,_,j),le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups,ke=((le?await le.get(j):void 0)?.resources??X?.resources??[]).map((ye)=>ye.trim()).filter(Boolean);return ke.length>0?ke:void 0}function Fs(T){if(!T||T.length===0)return{applyToApplication:!0};return{resources:T}}var Ys="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",Jr=["user","customer","workload"],Xs={user:async(T,_)=>_.sso?.getUser(T),customer:async(T,_)=>_.ciam?.getCustomer(T),workload:async(T,_)=>{let j=await _.workload?.getWorkloadIdentity?.(T);if(!j)return;let X=j.clientId??j.workloadId??j.claims.sub;return X?{...j,id:X}:void 0}};function Zs(T){if(T==="any")return Jr;let _=Array.isArray(T)?T:[T];return Jr.filter((j)=>_.includes(j))}function Qs(T){let _=T.headers.get("cookie");if(!_)return[];return _.split(";").map((j)=>j.slice(0,j.indexOf("=")===-1?j.length:j.indexOf("=")).trim()).filter(Boolean)}function ei(T,_){let j=T.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=Qs(T),le=new Set;for(let he of X){if(he.startsWith("ion.sso"))le.add("user");if(he.startsWith("ion.ciam"))le.add("customer")}let ge=X.length>0&&!le.has("user")&&!le.has("customer");return _.filter((he)=>{if(he==="workload")return j;if(X.length===0)return!1;return le.has(he)||ge})}function lt(T){return typeof T==="string"?T:T.id}function ti(T){let{subject:_,subjectType:j}=T,X;if(j==="user")X=_.sso?.scope;else if(j==="customer")X=_.ciam?.scope;else if(j==="workload")X=_.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function sr(T,_,j){let X=ti(T),le=_.filter((he)=>X.has(he));return{allow:j==="any"?le.length>0:_.length>0&&le.length===_.length,metadata:{reason:"scope",wantedScopes:_,matchedScopes:le}}}function Hr(T,_){if(T.targetType!==_.targetType||T.target!==_.id)return!1;return _.resource?T.resource===_.resource:T.resource===void 0}function pn(T,_){return(j)=>{if(T.length===0)return;let X=j.derivedEntitlements??[];if(X.length===0)return;let le=T.filter((he)=>X.some((ke)=>Hr(ke,he)));if(!(_==="any"?le.length>0:le.length===T.length))return;return X.filter((he)=>le.some((ke)=>Hr(he,ke)))}}function jn(T,_,j){return(X)=>{if(_.length===0||X.subjectType!=="workload")return;let le=J(T.config?.authz,X.subject);if(!le)return;let ge=_.filter((ke)=>le.has(ke));return(j==="any"?ge.length>0:ge.length===_.length)?ge:void 0}}function rr(T,_,j,X,le){return{allow:j==="ok",subject:_?.subject,subjectType:_?.subjectType,reason:j,decision:X,response(){if(j==="ok")return new Response(null,{status:204});if(j==="unauthenticated")return T.log.warn("authz.denied",{reason:j,...le()}),Response.json({error:"Unauthorized"},{status:401});if(j==="not_configured")return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"not_configured"},{status:503});return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"Forbidden"},{status:403})}}}function ni(T,_,j){return new Promise((X)=>{let le=[],ge=T.length,he=!1,ke=()=>{if(ge-=1,ge===0&&!he)he=!0,X({outcomes:le})};for(let ye of T)_(ye).then((fe)=>{if(le.push({principal:ye,decision:fe}),!he&&fe.allow){he=!0,X({matched:{principal:ye,decision:fe},outcomes:le});return}ke()},(fe)=>{j?.(ye,fe),le.push({principal:ye,decision:{allow:!1,metadata:{reason:"error"}}}),ke()})})}async function zt(T,_,j,X,le,ge,he){t(_,Ys);let ke=ei(T,Zs(j)),fe=(await Promise.all(ke.map(async(et)=>{let De=await Xs[et](T,_);if(!De?.id)return;let it=et==="workload"?De.derivedEntitlements:et==="user"||et==="customer"?nr(T,et):void 0;return{subject:De,subjectType:et,subjectId:De.id,derivedEntitlements:it}}))).filter((et)=>et!==void 0);if(fe.length===0)return rr(_,void 0,"unauthenticated",void 0,le);let ze=async(et)=>{let De=_.authz.accessIndex;if(!De?.isSubjectDisabled)return!1;return De.isSubjectDisabled(et.subjectId,et.subjectType)},Ye=async(et)=>{if(he){let De=he(et);if(De&&De.length>0){if(await ze(et))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:De}}}}if(ge){let De=ge(et);if(De&&De.length>0){if(await ze(et))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"claims",matchedIds:De.map((it)=>it.target),matchedClaims:[...new Set(De.map((it)=>it.claim))],roots:[...new Set(De.map((it)=>it.root).filter((it)=>Boolean(it)))]}}}}return X(et)},{matched:Qe,outcomes:ct}=await ni(fe,Ye,(et,De)=>{_.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:et.subjectId,subjectType:et.subjectType,error:De instanceof Error?De.message:String(De),...le()})});if(Qe){if(Qe.decision.metadata?.reason==="claims")_.log.info("authz.claims_honor",{"ion.operation":"authz.claims_honor","ion.outcome":"allow",subject:Qe.principal.subjectId,subjectType:Qe.principal.subjectType,matchedIds:Qe.decision.metadata.matchedIds,matchedClaims:Qe.decision.metadata.matchedClaims,roots:Qe.decision.metadata.roots,...le()});return rr(_,Qe.principal,"ok",Qe.decision,le)}let st=ct.length>0&&ct.every((et)=>{let De=et.decision.metadata?.reason;return De==="access_index_not_configured"||De==="error"}),_e=ct[0],Le=st?"not_configured":"forbidden";return rr(_,_e?.principal,Le,_e?.decision,le)}async function ri(T,_,j,X,le,ge="any"){return zt(T,_,ge,(he)=>_.authz.has(he.subjectId,j,X,le,he.subjectType),()=>({targetType:j,target:lt(X),resource:le?lt(le):void 0}),pn([{targetType:j,id:lt(X),resource:le?lt(le):void 0}],"any"),j==="permission"&&!le?jn(_,[lt(X)],"any"):void 0)}async function si(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasPermission(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"permission",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"permission",id:lt(j),resource:X?lt(X):void 0}],"any"),X?void 0:jn(_,[lt(j)],"any"))}async function ii(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasRole(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"role",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"role",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function oi(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasGroup(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"group",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"group",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function ai(T,_,j,X="any"){let le=j.map((he)=>({targetType:he.targetType,id:lt(he.target),resource:he.resource?lt(he.resource):void 0})),ge=j.filter((he)=>!he.resource&&he.targetType==="permission").map((he)=>lt(he.target));return zt(T,_,X,(he)=>_.authz.hasAny(he.subjectId,j,he.subjectType),()=>({targets:j.map((he)=>`${he.targetType}:${lt(he.target)}`)}),le.length>0?pn(le,"any"):void 0,ge.length>0?jn(_,ge,"any"):void 0)}async function ci(T,_,j,X="any"){let le=j.map((ke)=>({targetType:ke.targetType,id:lt(ke.target),resource:ke.resource?lt(ke.resource):void 0})),ge=j.length>0&&j.every((ke)=>!ke.resource&&ke.targetType==="permission"),he=j.map((ke)=>lt(ke.target));return zt(T,_,X,(ke)=>_.authz.hasAll(ke.subjectId,j,ke.subjectType),()=>({targets:j.map((ke)=>`${ke.targetType}:${lt(ke.target)}`)}),le.length>0?pn(le,"all"):void 0,ge?jn(_,he,"all"):void 0)}async function ui(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,[j],"any")),()=>({scope:j}))}async function di(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,j,"any")),()=>({scopes:j}))}async function li(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,j,"all")),()=>({scopes:j}))}function kt(T){return typeof T==="string"&&T.length>0?T:void 0}function Fr(T){let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}var Yr={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:Fr},google:{flow:"id_token",authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",jwksUri:"https://www.googleapis.com/oauth2/v3/certs",scope:"openid email profile",branding:{displayName:"Google",iconUrl:"https://www.gstatic.com/firebasejs/ui/2.0.0/images/auth/google.svg",colors:{light:"#ffffff",dark:"#131314",secondary:"#4285F4"},url:"https://accounts.google.com"},mapClaims:Fr},microsoft:{flow:"id_token",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(T)=>{let _=kt(T.email)??kt(T.preferred_username);return{sub:String(T.sub??T.oid??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}},apple:{flow:"id_token",authorizationUrl:"https://appleid.apple.com/auth/authorize",tokenUrl:"https://appleid.apple.com/auth/token",jwksUri:"https://appleid.apple.com/auth/keys",scope:"openid email name",extraAuthParams:{response_mode:"form_post"},branding:{displayName:"Apple",colors:{light:"#000000",dark:"#ffffff"},url:"https://appleid.apple.com"},mapClaims:(T)=>{let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:_}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(T)=>({sub:String(T.id??T.node_id??""),email:kt(T.email),name:kt(T.name)??kt(T.login),userName:kt(T.login),avatar:kt(T.avatar_url)})}};function ir(T){if(T==="magic-link")return;return Yr[T]}function Ln(T,_){if(_.type==="magic-link")return;let j=ir(_.type);if(!j)return;return{name:T,type:_.type,flow:j.flow,authorizationUrl:_.authorizationUrl??j.authorizationUrl,tokenUrl:_.tokenUrl??j.tokenUrl,jwksUri:_.jwksUri??j.jwksUri,userInfoUrl:_.userInfoUrl??j.userInfoUrl,scope:_.scope??j.scope,clientId:_.clientId,clientSecret:_.clientSecret,extraAuthParams:j.extraAuthParams,branding:{...j.branding,..._.branding},mapClaims:j.mapClaims,config:_}}function or(T){return{...ir(T.type)?.branding??{displayName:T.type},...T.branding}}function ar(T){if(!T)return[];return Object.entries(T).filter(([,_])=>_.enabled!==!1).map(([_,j],X)=>({name:_,config:j,index:X})).sort((_,j)=>{let X=_.config.order??Number.MAX_SAFE_INTEGER,le=j.config.order??Number.MAX_SAFE_INTEGER;if(X!==le)return X-le;return _.index-j.index}).map(({name:_,config:j})=>({name:_,config:j}))}var pi=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;function Nn(T){if(T===void 0)return;let _=T.trim().toLowerCase();if(!pi.test(_))throw Error(`Invalid cookiesDomain "${T}": expected a hostname such as "app.example.com" without a scheme, port, path, or leading dot.`);return _}function Xt(T){return T?` Domain=${T};`:""}var Xr=4000;function mi(T){return`Expires=${T.toUTCString()}`}function Zr(T){return`Path=${T.path};${Xt(T.domain)}${T.secure?" Secure;":""} SameSite=${T.sameSite};`}function dr(T,_,j,X){if(_.length>Xr)throw Error(`Display cookie ${T} value is ${_.length} bytes; the limit is ${Xr}.`);return`${T}=${_}; ${mi(j)}; ${Zr(X)}`}function Bt(T,_){return`${T}=; Max-Age=0; ${Zr(_)}`}function cr(T){if(!T)return;let _=T instanceof Date?T:new Date(T);return Number.isNaN(_.getTime())?void 0:_}function ur(T){return!T||T.getTime()>Date.now()}async function fi(T,_,j){let X=T.envelope.kind??"session";if(X==="discovered"){let ke=cr(T.envelope.expiresAt);return{...T,kind:X,live:Boolean(ke&&ur(ke))}}let le=_[`${T.prefix}.session`];if(!le)return{...T,kind:X,live:!1};let ge=await j.get(le);if(!ge||ge.authType!=="sso"&&ge.authType!=="ciam")return{...T,kind:X,live:!1};let he=cr(ge.expiresAt);return{...T,kind:X,live:ur(he),...he?{sessionExpiresAt:he}:{}}}function mn(T,_,j){let X=U(_);return T?.includes(`${X}=`)?[Bt(X,j)]:[]}function Qr(T,_,j,X,le){let ge=[...T.filter((ze)=>ze.kind==="session").slice(0,j),...T.filter((ze)=>ze.kind==="discovered").slice(0,X)],he=le?le(T,{max:j,maxDiscovered:X}):ge,ke=[...he.filter((ze)=>ze.kind==="session").slice(0,j),...he.filter((ze)=>ze.kind==="discovered").slice(0,X)];if(ke.some((ze)=>ze.name===_))return ke;let ye=T.find((ze)=>ze.name===_);if(!ye)return ke;return[...[ye,...ke.filter((ze)=>ze.kind==="session")].slice(0,j),...ke.filter((ze)=>ze.kind==="discovered")]}async function Rn(T){let _=U(T.cookiesPrefix),j=T.attr;if(T.displayCookie?.enabled!==!0)return mn(T.cookieHeader,T.cookiesPrefix,j);if(!T.sessionStore)return[];let X=m(T.user,T.projector),le={v:W,...T.tenantId?{tenantId:T.tenantId}:{},authType:T.authType,expiresAt:T.expiresAt.toISOString(),user:X},ge={name:_,prefix:T.cookiesPrefix,envelope:le,kind:"session",sessionExpiresAt:T.expiresAt,live:!0},he=re(T.cookieHeader),ke=T.sessionStore,ye=await Promise.all(B(T.cookieHeader).filter((Le)=>Le.name!==_).map((Le)=>fi(Le,he,ke))),fe=[ge,...ye.filter((Le)=>Le.live&&Le.kind==="session")].sort((Le,et)=>P(Le.sessionExpiresAt?.toISOString()??Le.envelope.expiresAt,et.sessionExpiresAt?.toISOString()??et.envelope.expiresAt)),ze=T.displayCookie.discovered?.enabled===!0?ye.filter((Le)=>Le.live&&Le.kind==="discovered"&&(!T.tenantId||Le.envelope.tenantId!==T.tenantId)).sort((Le,et)=>P(Le.envelope.expiresAt,et.envelope.expiresAt)):[],Ye=[...fe,...ze],Qe=te(T.displayCookie?.max),ct=V(T.displayCookie.discovered?.max),st=new Set(Qr(Ye,_,Qe,ct,T.trim).map((Le)=>Le.name)),_e=[dr(_,z(le),T.expiresAt,j)];for(let Le of ye)if(!st.has(Le.name))_e.push(Bt(Le.name,j));return _e}function gi(T){let _=re(T.cookieHeader),j=Object.keys(_).filter((_e)=>_e.startsWith(`${ee}.`)&&_e.endsWith(".profile"));if(!(T.displayCookie?.enabled===!0&&T.displayCookie.discovered?.enabled===!0))return j.map((_e)=>Bt(_e,T.attr));let le=T.now??new Date,ge=ne(T.displayCookie?.discovered?.ttlSeconds),he=new Date(le.getTime()+ge*1000),ke=V(T.displayCookie?.discovered?.max),ye=B(T.cookieHeader),fe=new Set(ye.filter((_e)=>(_e.envelope.kind??"session")==="session").flatMap((_e)=>_e.envelope.tenantId?[_e.envelope.tenantId]:[])),ze=new Map;for(let _e of ye){if(_e.envelope.kind!=="discovered"||!_e.envelope.tenantId)continue;let Le=cr(_e.envelope.expiresAt);if(Le&&ur(Le)&&!fe.has(_e.envelope.tenantId))ze.set(_e.envelope.tenantId,_e.envelope)}let Ye=m(T.user,T.projector);for(let _e of T.tenants){let Le=_e.tenantId.trim();if(!Le||fe.has(Le))continue;ze.set(Le,{v:W,kind:"discovered",tenantId:Le,authType:T.authType,expiresAt:he.toISOString(),user:Ye,..._e.tenantName?{tenantName:_e.tenantName}:{}})}let Qe=[...ze.values()].sort((_e,Le)=>P(_e.expiresAt,Le.expiresAt)).slice(0,ke),ct=new Set(Qe.map((_e)=>G(_e.tenantId??""))),st=Qe.map((_e)=>dr(G(_e.tenantId??""),z(_e),new Date(_e.expiresAt),T.attr));for(let _e of j)if(!ct.has(_e))st.push(Bt(_e,T.attr));return st}var gr=60000,ts=86400000,ns=600000,pr=256,It=new Map;function yi(T){if(typeof T?.ttlMs==="number"&&Number.isFinite(T.ttlMs))ns=Math.min(Math.max(T.ttlMs,gr),ts);if(typeof T?.maxEntries==="number"&&Number.isFinite(T.maxEntries)){pr=Math.max(1,Math.floor(T.maxEntries));while(It.size>pr){let _=It.keys().next().value;if(_===void 0)break;It.delete(_)}}}function es(T,_){It.delete(T),It.set(T,_);while(It.size>pr){let j=It.keys().next().value;if(j===void 0)break;It.delete(j)}}var An=new Map,mr=()=>Date.now();function hi(T){mr=T??(()=>Date.now())}var fr={};function ki(T){fr=T??{}}function Si(T){if(!T)return;if(/\bno-store\b/i.test(T))return gr;let _=/max-age\s*=\s*(\d+)/i.exec(T);if(!_)return;let j=Number(_[1]);return Number.isFinite(j)?j*1000:void 0}function wi(T){let j=Si(T)??ns;return Math.min(Math.max(j,gr),ts)}async function yr(T,_=3,j=1000,X=30000,le){let ge=Error("Placeholder Error");for(let he=0;he<=_;he++)try{return await T()}catch(ke){if(ge=ke instanceof Error?ke:Error(String(ke)),ke instanceof Error&&ke.message.includes("400"))throw ke;if(he===_)throw ge;let ye=Math.min(j*2**he,X),fe=Math.random()*0.1*ye;await new Promise((ze)=>setTimeout(ze,ye+fe)),le?.warn(`Retry attempt ${he+1} after ${ye+fe}ms delay`)}throw ge}async function In(T,_,j){let X=It.get(T);if(!j?.forceRefresh&&X&&X.expiresAt>mr())return es(T,X),X.jwks;let le=An.get(T);if(le)return le;let ge=(async()=>{try{return await yr(async()=>{let he=await fetch(T,{headers:i});if(!he.ok){let fe=await F(he);throw _?.warn("JWKS endpoint returned an error",{"ion.operation":"jwks.fetch","ion.outcome":"degraded",reason:"upstream_error",status:he.status,contentType:fe.contentType,excerpt:fe.excerpt}),Error(`Failed to fetch JWKS (${he.status})`)}let ke=await a(he,{log:_,operation:"jwks.fetch"}),ye=wi(he.headers.get("cache-control"));return es(T,{jwks:ke,expiresAt:mr()+ye,importedKeys:new Map}),ke},fr.maxRetries,fr.baseDelayMs,void 0,_)}catch(he){let ke=It.get(T);if(ke)return _?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),ke.jwks;throw he}finally{An.delete(T)}})();return An.set(T,ge),ge}function bi(T){if(T){It.delete(T),An.delete(T);return}It.clear(),An.clear()}async function Ci(T,_,j){return(await rs(T,_,j)).jwk}async function rs(T,_,j){if(!_?.trim())throw Error("JWT header missing kid");await In(T,j);let X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!le)await In(T,j,{forceRefresh:!0}),X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!X||!le)throw Error("Public key not found");return{jwk:le,entry:X}}async function hr(T,_,j,X,le){let{jwk:ge,entry:he}=await rs(T,_,le),ke=`${_}\x00${j}`,ye=he.importedKeys.get(ke);if(ye)return ye;let fe=X(ge);return fe.catch(()=>{if(he.importedKeys.get(ke)===fe)he.importedKeys.delete(ke)}),he.importedKeys.set(ke,fe),fe}async function vi(T,_){let j=T.keys.find((X)=>X.kid===_);if(!j)throw Error("Public key not found");return ss(j)}function ss(T){return crypto.subtle.importKey("jwk",{kty:T.kty,n:T.n,e:T.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function Ri(T,_,j){return hr(T,_,"rs256",ss,j)}var lr={RS256:{kty:"RSA",importParams:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},verifyParams:{name:"RSASSA-PKCS1-v1_5"}},ES256:{kty:"EC",crv:"P-256",importParams:{name:"ECDSA",namedCurve:"P-256"},verifyParams:{name:"ECDSA",hash:"SHA-256"}}};async function kr(T,_,j,X){if(typeof j!=="string"||!(j in lr))throw Error(`Unsupported JWT alg "${String(j)}" (allowed: ${Object.keys(lr).join(", ")})`);let le=lr[j];return{key:await hr(T,_,`oidc:${j}`,(he)=>{if(he.kty!==le.kty)throw Error(`JWK type "${he.kty}" does not match token alg "${j}"`);if(le.kty==="EC"){let ke=he;if(ke.crv!==le.crv)throw Error(`JWK curve "${String(ke.crv)}" does not match token alg "${j}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:ke.crv,x:ke.x,y:ke.y},le.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:he.kty,n:he.n,e:he.e},le.importParams,!1,["verify"])},X),algorithm:le.verifyParams}}function _t(T=32){let _=new Uint8Array(T);return crypto.getRandomValues(_),Array.from(_,(j)=>j.toString(16).padStart(2,"0")).join("").substring(0,T)}function $n(T){let _="";return T.forEach((j)=>{_+=String.fromCharCode(j)}),btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function as(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.padEnd(_.length+(4-_.length%4)%4,"="),X=atob(j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function is(T){let _=new TextDecoder().decode(as(T));return JSON.parse(_)}async function Pn(T){let _=new TextEncoder().encode(T),j=await crypto.subtle.digest("SHA-256",_);return $n(new Uint8Array(j))}function wr(T){let _=new URL(T.authorizationUrl);if(_.searchParams.set("client_id",T.clientId),_.searchParams.set("redirect_uri",T.redirectUri),_.searchParams.set("response_type","code"),_.searchParams.set("scope",T.scope),_.searchParams.set("state",T.state),T.codeChallenge)_.searchParams.set("code_challenge",T.codeChallenge),_.searchParams.set("code_challenge_method","S256");if(T.nonce)_.searchParams.set("nonce",T.nonce);for(let[j,X]of Object.entries(T.extraParams??{}))_.searchParams.set(j,X);return _.toString()}async function br(T){let _=new URLSearchParams;if(_.append("grant_type","authorization_code"),_.append("code",T.code),_.append("redirect_uri",T.redirectUri),_.append("client_id",T.clientId),T.clientSecret)_.append("client_secret",T.clientSecret);if(T.codeVerifier)_.append("code_verifier",T.codeVerifier);let j=await fetch(T.tokenUrl,{method:"POST",headers:{...h,...i},body:_.toString()}),X=await a(j,{log:T.log,operation:"oidc.token.exchange"});if(!j.ok){let le=X,ge=le.error==="invalid_client"&&!T.clientSecret;throw T.log?.error(ge?"OIDC authorization-code exchange failed: no client_secret was configured; the provider may require a confidential client":"OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":j.status,oidc_error:le.error,...ge?{client_auth:"none"}:{}}),Error(`Token exchange failed: ${le.error||j.statusText} - ${le.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var cs=60;function xn(T){return T.trim().replace(/\/$/,"")}function us(T){let{claims:_,audience:j}=T,X=xn(T.issuer),le=T.nowSec??Math.floor(Date.now()/1000),ge=T.clockSkewSec??cs,he=_.iss;if(typeof he!=="string"||xn(he)!==X)throw Error("ID token issuer mismatch");let ke=_.aud,ye=Array.isArray(ke)?ke.includes(j):typeof ke==="string"&&ke===j,fe=typeof _.azp==="string"&&_.azp===j;if(!ye&&!fe)throw Error("ID token audience mismatch");if(typeof _.exp!=="number")throw Error("ID token missing exp");if(_.exp<le-ge)throw Error("ID token expired");if(T.expectedNonce!==void 0){if(_.nonce!==T.expectedNonce)throw Error("ID token nonce mismatch")}}async function ds(T,_,j){let X=T.split(".");if(X.length!==3)throw Error("Invalid JWT");let le=is(X[0]),ge=is(X[1]),he=as(X[2]),{key:ke,algorithm:ye}=await kr(_,le.kid,le.alg,j),fe=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(ye,ke,he,fe))throw Error("Invalid JWT signature");return{header:le,payload:ge}}async function Zt(T){let{payload:_}=await ds(T.idToken,T.jwksUri,T.log);return us({claims:_,issuer:T.issuer,audience:T.audience,clockSkewSec:T.clockSkewSec,expectedNonce:T.expectedNonce}),_}var Ai="http://schemas.openid.net/event/backchannel-logout";async function Cr(T){let{payload:_}=await ds(T.logoutToken,T.jwksUri,T.log),j=xn(T.issuer),X=_.iss;if(typeof X!=="string"||xn(X)!==j)throw Error("Logout token issuer mismatch");let le=_.aud,ge=Array.isArray(le)?le.includes(T.audience):typeof le==="string"&&le===T.audience,he=typeof _.azp==="string"&&_.azp===T.audience;if(!ge&&!he)throw Error("Logout token audience mismatch");if(_.nonce!=null)throw Error("Logout token must not contain a nonce");let ke=_.events;if(!(typeof ke==="object"&&ke!==null&&!Array.isArray(ke)&&Object.hasOwn(ke,Ai)))throw Error("Logout token missing back-channel logout event");let fe=typeof _.sid==="string"&&_.sid.length>0,ze=typeof _.sub==="string"&&_.sub.length>0;if(!fe&&!ze)throw Error("Logout token missing sid and sub");if(typeof _.exp==="number"){let Ye=Math.floor(Date.now()/1000),Qe=T.clockSkewSec??cs;if(_.exp<Ye-Qe)throw Error("Logout token expired")}return _}var Ii=3600000,Ti=60000,xi=86400000,Pi=256,Gt=new Map,Tn=new Map;function os(T,_){Gt.delete(T),Gt.set(T,_);while(Gt.size>Pi){let j=Gt.keys().next().value;if(j===void 0)break;Gt.delete(j)}}var Sr=()=>Date.now();function Ui(T){Sr=T??(()=>Date.now())}function Ei(T){if(T){Gt.delete(T),Tn.delete(T);return}Gt.clear(),Tn.clear()}function Di(T){let _=T?/max-age\s*=\s*(\d+)/i.exec(T):null,j=_?Number(_[1]):Number.NaN,X=Number.isFinite(j)?j*1000:Ii;return Math.min(Math.max(X,Ti),xi)}async function vr(T){let _=Gt.get(T);if(_&&_.expiresAt>Sr())return os(T,_),_.endpoints;let j=Tn.get(T);if(j)return j;let X=(async()=>{try{let le=T.replace(/\/$/,""),ge=await fetch(`${le}/.well-known/openid-configuration`,{headers:i});if(!ge.ok)throw Error(`OIDC discovery failed for ${T} with status ${ge.status}`);let he=await a(ge),ke={authorizationUrl:typeof he.authorization_endpoint==="string"?he.authorization_endpoint:void 0,tokenUrl:typeof he.token_endpoint==="string"?he.token_endpoint:void 0,jwksUri:typeof he.jwks_uri==="string"?he.jwks_uri:void 0,userInfoUrl:typeof he.userinfo_endpoint==="string"?he.userinfo_endpoint:void 0};return os(T,{endpoints:ke,expiresAt:Sr()+Di(ge.headers.get("cache-control"))}),ke}catch(le){let ge=Gt.get(T);if(ge)return ge.endpoints;throw le}finally{Tn.delete(T)}})();return Tn.set(T,X),X}async function Rr(T,_){let j=await fetch(T,{headers:{Authorization:`Bearer ${_}`,...i,"User-Agent":"ionite-ciam"}});if(!j.ok)throw Error(`UserInfo request failed with status ${j.status}`);return await a(j)}function Mi(T){let _=T.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),j=atob(_),X=new Uint8Array(j.length);for(let le=0;le<j.length;le++)X[le]=j.charCodeAt(le);return X}async function Ar(T){let _=Math.floor(Date.now()/1000),j={alg:"ES256",kid:T.keyId,typ:"JWT"},X={iss:T.teamId,iat:_,exp:_+(T.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:T.clientId},le=$n(new TextEncoder().encode(JSON.stringify(j))),ge=$n(new TextEncoder().encode(JSON.stringify(X))),he=`${le}.${ge}`,ke=await crypto.subtle.importKey("pkcs8",Mi(T.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),ye=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},ke,new TextEncoder().encode(he));return`${he}.${$n(new Uint8Array(ye))}`}function Oi(T){for(let _=0;_<T.length;_++){let j=T.charCodeAt(_);if(j<=31||j===127)return!0}return!1}function _i(T,_){let j=null;try{j=new URL(T,_)}catch{j=null}let X="";try{X=new URL(_).origin}catch{X=""}return{candidate:T,url:j,requestOrigin:X}}function ls(T,_,j){let X=_i(T,j),le=!1;for(let ge of _){let he=ge(X);if(he==="deny")return!1;if(he==="allow")le=!0}return le}function ps(){return({candidate:T,url:_})=>{if(Oi(T))return"deny";if(T.includes("\\"))return"deny";if(T.startsWith("//"))return"deny";if(!_)return"deny";if(_.protocol!=="http:"&&_.protocol!=="https:")return"deny";if(_.username||_.password)return"deny";return"abstain"}}function ms(){return({candidate:T})=>T.startsWith("/")&&!T.startsWith("//")&&!T.startsWith("/\\")?"allow":"abstain"}function fs(){return({url:T,requestOrigin:_})=>T&&_&&T.origin===_?"allow":"abstain"}function ji(...T){let _=new Set(T.map((j)=>{try{return new URL(j).origin}catch{return j}}));return({url:j})=>j&&_.has(j.origin)?"allow":"abstain"}function Li(...T){let _=T.map((j)=>j.toLowerCase());return({url:j})=>{if(!j)return"abstain";let X=j.hostname.toLowerCase();for(let le of _)if(le.startsWith(".")){if(X===le.slice(1)||X.endsWith(le))return"allow"}else if(X===le)return"allow";return"abstain"}}function Ir(){return[ps(),ms(),fs()]}function gs(T,_,j){if(!T)return!1;return ls(T,_,j)}function Tr(T,_){if(!T)return _.fallback;return ls(T,_.rules,_.requestUrl)?T:_.fallback}var Ni={rules:Ir(),fallback:"/"};function $i(T,_,j="redirect"){let X=new URL(T.url).searchParams.get(j)??void 0;return gs(X,_.rules,T.url)?{redirect:X}:void 0}function Wi(T,_){let j=T.context;return Tr(j?.redirect,{rules:_.rules,fallback:_.fallback,requestUrl:T.request.url})}function Qt(T,_,j){if(T instanceof Response)return{response:T};if(typeof T==="string")return{location:Tr(T,{rules:Ir(),fallback:_,requestUrl:j})};return{location:_}}function sn(T,_){if(_.length===0)return T;let j=new Headers(T.headers);for(let X of _)j.append("Set-Cookie",X);return new Response(T.body,{status:T.status,statusText:T.statusText,headers:j})}var Wn="ciam",Vi="id_token",qi="access_token";function zi(T,_,j,X,le,ge){if(!j&&!X)return;let he=new WeakMap,ke={...j,...X},ye={...ke,magicLinkTtl:ke.magicLinkTtl??3600,sessionTtl:ke.sessionTtl??86400,cookiesSecure:ke.cookiesSecure!==void 0?ke.cookiesSecure:!0,cookiesSameSite:ke.cookiesSameSite!==void 0?ke.cookiesSameSite:"Strict",cookiesPrefix:ke.cookiesPrefix??(ke.ciamId?`ion.ciam.${ke.ciamId}`:"ion.ciam"),cookiesPath:ke.cookiesPath??"/",cookiesDomain:Nn(ke.cookiesDomain)};function fe(){if(!ye.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return ye.sessionStore}function ze(){fe()}let Ye=T.callbackParams??l(oe("ionite.ciam")),Qe=T.idTokenClaims??l(y("ionite.ciam")),ct=T.tokenResponse??l(ie("ionite.ciam"));function st(me=32){let we=new Uint8Array(me);return crypto.getRandomValues(we),Array.from(we,(be)=>be.toString(16).padStart(2,"0")).join("").substring(0,me)}function _e(me,we,be,Re=ye.cookiesSameSite??"Strict"){if(!ye)throw Error("ionite CIAM Manager not initialized");if(me=`${ye.cookiesPrefix}.${me}`,typeof we!=="string")we=btoa(JSON.stringify(we));let Ue;if(be instanceof Date)Ue=`Expires=${be.toUTCString()}`;else if(typeof be==="number")Ue=`Max-Age=${be}`;else throw Error("Invalid expires type",be);if(we.length>4000)throw Error(`Error setting cookie: ${me}. Cookie length is: ${we.length}`);return`${me}=${we}; ${Ue}; Path=${ye.cookiesPath};${Xt(ye.cookiesDomain)} HttpOnly;${ye.cookiesSecure?" Secure;":""} SameSite=${Re};`}function Le(me){if(!ye)throw Error("ionite CIAM Manager not initialized");return`${ye.cookiesPrefix}.${me}=; Max-Age=0; Path=${ye.cookiesPath};${Xt(ye.cookiesDomain)} HttpOnly;${ye.cookiesSecure?" Secure;":""} SameSite=${ye.cookiesSameSite};`}function et(me,we,be=!1){if(!ye)throw Error("ionite CIAM Manager not initialized");let Re=we.headers.get("cookie");if(!Re)return null;let Ue=`${ye.cookiesPrefix}.${me}`,je=Re.split(";").find((Ee)=>Ee.trim().startsWith(`${Ue}=`));if(!je)return null;let We=je.indexOf("="),qe=je.substring(We+1).trim();if(!be)return qe;try{let Ee=atob(qe);return JSON.parse(Ee)}catch(Ee){return _.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:Ue},Ee),null}}function De(me){return`cstate_${me}`}async function it(me,we,be,Re){let Ue=await ye.afterLogin?.({...we,request:me,context:be,displayCookie:ye.displayCookie,displayCookieAttributes:bt()}),je=Qt(Ue,"/",me.url);if(je.response)return sn(je.response,Re.map(([,We])=>We));return new Response(we.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",je.location],...Re]})}function pt(me,we){return["Set-Cookie",_e("session",me,we)]}function bt(){return{path:ye.cookiesPath??"/",domain:ye.cookiesDomain,secure:ye.cookiesSecure!==!1,sameSite:ye.cookiesSameSite??"Strict"}}function mt(){return[["Set-Cookie",Le("session")],["Set-Cookie",Bt(`${ye.cookiesPrefix}.profile`,bt())]]}function Rt(me){if(ye.displayCookie?.enabled===!0)return[];return mn(me.headers.get("cookie"),ye.cookiesPrefix??"ion.ciam",bt()).map((we)=>["Set-Cookie",we])}async function Tt(me,we,be){return(await Rn({cookieHeader:me.headers.get("cookie"),sessionStore:ye.sessionStore,cookiesPrefix:ye.cookiesPrefix??"ion.ciam",authType:"ciam",tenantId:ye.tenantId,expiresAt:be,user:we,projector:ye.displayUser,displayCookie:ye.displayCookie,trim:ye.trimDisplayCookies,attr:bt()})).map((Ue)=>["Set-Cookie",Ue])}function Mt(me){if(!me)return;if(me instanceof Date)return me;let we=new Date(me);return Number.isNaN(we.getTime())?void 0:we}async function kn(me){let we=et("session",me);if(!we)return;let be=await fe().get(we);if(be&&ye.tenantId&&be.tenantId&&be.tenantId!==ye.tenantId)return;if(be?.authType!=="ciam")return;let Re=Mt(be.expiresAt);if(Re&&Date.now()>Re.getTime()){await fe().delete(we);return}return be}async function Jt(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we=he.get(me);if(we)return we;let be=Sn(me);return he.set(me,be),be}async function Sn(me){try{let we=await kn(me);if(!we?.claims?.sub)return{status:"unauthenticated"};return vn(me,"customer",we.entitlements),{status:"authenticated",value:xt(we.claims)}}catch(we){return _.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},we),{status:"degraded",error:we instanceof Error?we:void 0}}}async function un(me){let we=await Jt(me);return we.status==="authenticated"?we.value:void 0}async function Ht(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we;try{we=await un(me)}catch{we=void 0}let be=await ye.beforeLogout?.({request:me,user:we});try{let Ae=et("session",me);if(Ae)await fe().delete(Ae)}catch(Ae){_.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Ae)}let Re=mt(),Ue=await ye.afterLogout?.({request:me,context:be}),je=Qt(Ue,"/",me.url);if(je.response)return sn(je.response,Re.map(([,Ae])=>Ae));let We=je.location??"/",qe=me.headers.get("accept");if(qe?.includes(s)||qe?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:We}),{status:200,headers:[["Content-Type",s],...Re]});return new Response("Logged out",{status:302,headers:[["Location",We],...Re]})}function Ft(me){return me.id||me.email||`ciam-${me.userName}`}function nn(me,we,be){return{sub:Ft(me),iss:Wn,aud:Wn,typ:Vi,exp:Math.floor(be.getTime()/1000),iat:Math.floor(Date.now()/1000),email:me.email,name:me.name,preferred_username:me.userName,picture:me.avatar,sid:we}}function dn(me,we,be){return{sub:me,iss:Wn,aud:Wn,typ:qi,exp:Math.floor(be.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:we,scope:"openid profile email"}}function xt(me){let we=me.exp?new Date(me.exp*1000):new Date;return{id:me.sub,userName:me.preferred_username??"",name:me.name??"",email:me.email??"",avatar:me.picture,userType:"customer",ciam:{profile:me,scope:"openid profile email",tokenType:"Bearer",expires:we}}}async function ln(me){if(!ye)throw Error("ionite CIAM Manager not initialized");if(!le)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:r});if(!await le.getWorkloadIdentity(me))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:r});let be,Re;try{if(!me.headers.get("content-type")?.includes(s))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:r});let Te=await me.text(),xe=JSON.parse(Te);Re=typeof xe?.redirect==="string"&&xe.redirect.length>0?xe.redirect:void 0;let Ne={userName:xe.userName,name:xe.name,email:xe.email,avatar:xe.avatar},Oe=await T.customer.validate(Ne);if(Oe.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:r});be=Oe.value}catch(Ie){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:r})}let je=new URL(me.url).searchParams.get("ttl"),We=je?parseInt(je,10):ye.magicLinkTtl??3600;if(Number.isNaN(We)||We<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:r});let qe=st(32),Ee=new Date(Date.now()+We*1000);if(!ye.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:r});try{await ye.magicLinkStore.create(qe,be,Ee)}catch(Ie){return _.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},Ie),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:r})}let Ae=new URL(me.url),Se=ye.magicLinkLoginUrl||"/magic-link/login",ve=new URL(Se,Ae.origin);if(ve.searchParams.set("token",qe),Re)ve.searchParams.set("redirect",Re);return new Response(JSON.stringify({magicLink:ve.toString(),expiresAt:Ee.toISOString()}),{status:200,headers:r})}async function Yt(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let be=new URL(me.url).searchParams.get("token");if(!be)return it(me,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!ye.magicLinkStore)return it(me,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let Re=await ye.magicLinkStore.getAndDelete(be);if(!Re)return it(me,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let Ue=new Date(Date.now()+(ye.sessionTtl??86400)*1000),je=st(32),We=Ft(Re.customer),qe=nn(Re.customer,je,Ue),Ee=dn(We,je,Ue),Ae=xt(qe),Se;try{let Ie={sid:je,sub:We,authType:"ciam",tenantId:ye.tenantId,expiresAt:Ue,claims:qe,accessClaims:Ee,createdAt:new Date};await fe().create(Ie),Se=Ie}catch(Ie){throw _.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},Ie),Ie}if(ye.customerStore)try{let Ie=Ae.id;if(Ie){let Te=new Date,xe=await ye.customerStore.get(Ie);if(xe||ye.enableJitUserProvisioning){let Ne={...xe??{},...Ae,id:Ie,tenantId:xe?.tenantId,createdAt:xe?.createdAt??Te,updatedAt:Te,userType:xe?.userType??"customer"};await ye.customerStore.upsert(Ne)}}}catch(Ie){_.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},Ie)}let ve=[pt(je,Ue),...await Tt(me,Ae,Ue)];return it(me,{ok:!0,user:Ae,session:Se},void 0,ve)}function Pt(me,we=200,be=[]){return new Response(JSON.stringify(me),{status:we,headers:[["Content-Type",s],...be]})}function At(me,we){try{return new URL(me).toString()}catch{let be=new URL(we).origin,Re=ye.cookiesSecure?be.replace(/^http:\/\//,"https://"):be;return new URL(me,Re).toString()}}function $t(){let me=ye.customerLoginUrl||"/auth/customer/login",we=me.includes("?")?"&":"?";return ar(ye.providers).map(({name:be,config:Re})=>{let Ue=or(Re);return{name:be,type:Re.type,displayName:Ue.displayName,loginUrl:`${me}${we}provider=${encodeURIComponent(be)}`,iconUrl:Ue.iconUrl,colors:Ue.colors,url:Ue.url}})}async function Wt(me){if(!me)return{};let{authorizationUrl:we,tokenUrl:be,jwksUri:Re,userInfoUrl:Ue}=me,je=me.config.authority;if(je&&(!we||!be||me.flow==="id_token"&&!Re))try{let qe=await vr(je);we=we??qe.authorizationUrl,be=be??qe.tokenUrl,Re=Re??qe.jwksUri,Ue=Ue??qe.userInfoUrl}catch(qe){_.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},qe)}return{authorizationUrl:we,tokenUrl:be,jwksUri:Re,userInfoUrl:Ue}}async function rn(me){if(me.type==="apple"){let{teamId:we,keyId:be,privateKey:Re,clientId:Ue}=me.config;if(we&&be&&Re&&Ue)return Ar({teamId:we,keyId:be,privateKey:Re,clientId:Ue})}return me.clientSecret}async function Ot(me){fe();let be=new URL(me.url).searchParams.get("provider");if(!be)return Pt({error:"Missing required query parameter: provider"},400);let Re=ye.providers?.[be];if(!Re||Re.enabled===!1||Re.type==="magic-link")return Pt({error:`Unknown or disabled CIAM provider: ${be}`},404);let Ue=Ln(be,Re);if(!Ue?.clientId)return Pt({error:`CIAM provider ${be} is not fully configured`},500);let je=await Wt(Ue);if(!je.authorizationUrl)return Pt({error:`CIAM provider ${be} is missing an authorization endpoint`},500);let We=ye.customerCallbackUrl||"/auth/customer/callback",qe=At(We,me.url),Ee=_t(),Ae=_t(64),Se=_t(),ve=Ue.flow==="id_token",Ie=ve?await Pn(Ae):void 0,Te=await ye.beforeLogin?.({request:me}),xe=wr({authorizationUrl:je.authorizationUrl,clientId:Ue.clientId,redirectUri:qe,scope:Ue.scope,state:Ee,codeChallenge:Ie,nonce:Se,extraParams:Ue.extraAuthParams}),Ne={provider:be,state:Ee,codeVerifier:ve?Ae:void 0,nonce:Se,redirectUri:qe,...Te===void 0?{}:{context:Te}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",xe],["Set-Cookie",_e(De(Ee),Ne,ye.loginStateTtl??600,"Lax")]]})}async function Ve(me){if(me.method==="POST"){if((me.headers.get("content-type")??"").includes(D)){let be=await me.text();return Object.fromEntries(new URLSearchParams(be).entries())}}return Object.fromEntries(new URL(me.url).searchParams.entries())}let Xe=!1;async function Be(me,we,be,Re){let Ue=me.config.claimsAsEntitlements;if(!Ue?.claims?.length||me.type==="magic-link")return;if(ye.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Xe)Xe=!0,_.warn("CIAM claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.ciam.claims.incapable","ion.module":"ciam","ion.outcome":"degraded"});return}return bn({block:Ue,claims:we,accessClaims:Cn(Re),subjectType:"customer",subjectId:be,catalog:ge?.catalogView?.(),log:_})}async function Ze(me,we,be){let Re=me.mapClaims(we);if(!Re.sub)return{ok:!1};let Ue=`${me.name}:${Re.sub}`,je={id:Ue,userName:Re.userName||Re.email||Ue,name:Re.name||"",email:Re.email||"",avatar:Re.avatar,userType:"customer"},We=Ue;if(ye.customerStore){let Ie=await ye.customerStore.lookup(je)??await ye.customerStore.get(Ue);if(We=Ie?.id??Ue,!Ie&&!ye.enableJitUserProvisioning)return _.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let Te=new Date,xe={...Ie??{},...je,id:We,tenantId:Ie?.tenantId,createdAt:Ie?.createdAt??Te,updatedAt:Te,userType:Ie?.userType??"customer"};await ye.customerStore.upsert(xe)}let qe=new Date(Date.now()+(ye.sessionTtl??86400)*1000),Ee=_t(32),Ae={sub:We,iss:me.name,aud:me.clientId,exp:Math.floor(qe.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Re.email,name:Re.name,preferred_username:Re.userName??Re.email,picture:Re.avatar,sid:Ee},Se={sid:Ee,sub:We,authType:"ciam",tenantId:ye.tenantId,expiresAt:qe,claims:Ae,accessClaims:{sub:We,sid:Ee,scope:me.scope},entitlements:await Be(me,we,We,be),createdAt:new Date},ve=fe();try{await ve.create(Se)}catch(Ie){if(!await ve.get(Ee))throw Ie;await ve.update(Ee,Se)}return{ok:!0,claims:Ae,sid:Ee,expires:qe}}async function Je(me){fe();let we,be,Re=(Ue)=>{let je=we?[["Set-Cookie",Le(we)]]:[];return it(me,{ok:!1,error:Ue},be,je)};try{let Ue=await Ve(me),je=await Ye.validate(Ue);if(je.issues||!je.value)return Re(Error("Invalid CIAM callback parameters"));let{code:We,state:qe}=je.value;if(!qe)return Re(Error("Missing CIAM callback state"));we=De(qe);let Ee=et(we,me,!0);if(be=Ee?.context,!Ee?.provider||!Ee.state||Ee.state!==qe)return _.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM callback state verification failed"));let Ae=ye.providers?.[Ee.provider];if(!Ae)return Re(Error("Unknown CIAM provider"));let Se=Ln(Ee.provider,Ae);if(!Se?.clientId)return Re(Error("CIAM provider not configured"));let ve=await Wt(Se);if(!ve.tokenUrl)return Re(Error("CIAM provider missing token endpoint"));let Ie=await rn(Se),Te=await br({tokenUrl:ve.tokenUrl,clientId:Se.clientId,clientSecret:Ie,redirectUri:Ee.redirectUri||At(ye.customerCallbackUrl||"/auth/customer/callback",me.url),code:We,codeVerifier:Se.flow==="id_token"?Ee.codeVerifier:void 0,log:_}),xe;if(Se.flow==="id_token"){let Fe=Se.config.authority;if(!Te.id_token||!ve.jwksUri||!Fe)return Re(Error("CIAM id_token flow misconfigured"));if(!Ee.nonce)return Re(Error("CIAM callback state cookie missing nonce"));if((await ct.validate(Te)).issues)return _.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM token response validation failed"));xe=await Zt({idToken:Te.id_token,jwksUri:ve.jwksUri,issuer:Fe,audience:Se.clientId,expectedNonce:Ee.nonce,log:_});let at=await Qe.validate(xe);if(!at.issues)xe=at.value}else{if(!ve.userInfoUrl)return Re(Error("CIAM provider missing userinfo endpoint"));xe=await Rr(ve.userInfoUrl,Te.access_token);let Fe=Se.config.authority;if(Te.id_token&&ve.jwksUri&&Fe){let rt=await Zt({idToken:Te.id_token,jwksUri:ve.jwksUri,issuer:Fe,audience:Se.clientId,expectedNonce:Ee.nonce||void 0,log:_}),at=typeof rt.sub==="string"?rt.sub:"";if(at){if(typeof xe.sub==="string"&&xe.sub.length>0&&xe.sub!==at)return _.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM UserInfo sub mismatch"));xe.sub=at}}if(typeof xe.sub!=="string"||xe.sub.length===0)return _.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM UserInfo response missing sub"))}let Ne=await Ze(Se,xe,Te.access_token);if(!Ne.ok)return Re(Error("Failed to persist CIAM customer"));let Oe=xt(Ne.claims);_.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:Se.name});let Ge=[["Set-Cookie",Le(we)],pt(Ne.sid,Ne.expires),...await Tt(me,Oe,Ne.expires)];return it(me,{ok:!0,user:Oe,session:void 0},be,Ge)}catch(Ue){return _.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},Ue),Re(Ue)}}async function He(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we=ye.magicLinkUrl||"/magic-link",be=ye.magicLinkLoginUrl||"/magic-link/login",Re=ye.logoutUrl||"/auth/customer/logout",Ue=ye.customerLoginUrl||"/auth/customer/login",je=ye.customerCallbackUrl||"/auth/customer/callback",We=ye.customerProvidersUrl||"/auth/customer/providers",qe=new URL(me.url).pathname,Ee=(Ne)=>{if(!Ne)return;try{return new URL(Ne).pathname}catch{return Ne.startsWith("/")?Ne:`/${Ne}`}};if(Ee(we)===qe&&me.method==="POST")return ln(me);if(Ee(be)===qe&&me.method==="GET")return Yt(me);if(Ee(Re)===qe&&me.method==="GET")return Ht(me);if(Ee(We)===qe&&me.method==="GET")return Pt({providers:$t()});if(Ee(Ue)===qe&&me.method==="GET")return Ot(me);if(Ee(je)===qe&&(me.method==="GET"||me.method==="POST"))return Je(me);return new Response("Not Found",{status:404})}async function ut(me){if((ye.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Rt(me)});let we=await Jt(me);if(we.status==="degraded")return new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r});if(we.status==="unauthenticated")return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:r});let be=Mt(we.value.ciam?.expires),Re=ye.displayCookie?.enabled===!0?be&&!et("profile",me)?await Tt(me,we.value,be):[]:Rt(me),Ue=ye.userEndpoint==="display"?m(we.value,ye.displayUser):we.value;return new Response(JSON.stringify(Ue),{headers:[["Content-Type",s],...Re]})}let Ce;return Ce={...ye,describe:()=>({module:"ciam",active:!0,ready:Ce.isReady?.()??!0,magicLinkTtl:ye.magicLinkTtl,loginStateTtl:ye.loginStateTtl,sessionTtl:ye.sessionTtl,cookies:{prefix:ye.cookiesPrefix,path:ye.cookiesPath,secure:ye.cookiesSecure,sameSite:ye.cookiesSameSite,domain:ye.cookiesDomain},displayCookie:ye.displayCookie,jit:{enabled:ye.enableJitUserProvisioning===!0,customerStore:ye.customerStore!==void 0},sessionStore:ye.sessionStore!==void 0,magicLinkStore:ye.magicLinkStore!==void 0,providers:Object.entries(ye.providers??{}).map(([me,we])=>({name:me,type:we.type,enabled:we.enabled!==!1,order:we.order,branding:we.branding,authority:we.authority,authorizationUrl:we.authorizationUrl,tokenUrl:we.tokenUrl,jwksUri:we.jwksUri,userInfoUrl:we.userInfoUrl,clientId:we.clientId,scope:we.scope,...we.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...we.claimsAsEntitlements.claims],expand:we.claimsAsEntitlements.expand===!0,resources:we.claimsAsEntitlements.expand===!0&&we.claimsAsEntitlements.resources===!0,capable:ye.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},loginUrl:`${ye.customerLoginUrl??""}?provider=${encodeURIComponent(me)}`})),urls:{magicLinkUrl:ye.magicLinkUrl??"",magicLinkLoginUrl:ye.magicLinkLoginUrl??"",customerUrl:ye.customerUrl??"",customerLoginUrl:ye.customerLoginUrl??"",customerCallbackUrl:ye.customerCallbackUrl??"",customerProvidersUrl:ye.customerProvidersUrl??"",logoutUrl:ye.logoutUrl??""}}),getCustomer:un,resolveCustomer:Jt,logout:Ht,handler:He,customerHandler:ut,listCustomerProviders:$t},Ce}async function Bi(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),_.ciam?.getCustomer(T)}async function Vn(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await _.ciam?.resolveCustomer(T)??{status:"unauthenticated"}}var Gi="urn:ietf:params:scim:schemas:core:2.0:User",ys="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Ki="urn:ietf:params:scim:schemas:core:2.0:Group";function xr(T,_,j){let le=(_==="group"?T.resources:void 0)?.map((ge)=>typeof ge==="string"?ge:ge.id).filter(Boolean);return{schemas:[Ki,e],id:T.id,externalId:T.providerId,displayName:T.displayName??T.name,members:j,[e]:{type:_,requestable:T.requestable,riskLevel:T.riskLevel??f,providerId:T.providerId,requestUrl:T.requestUrl,source:T.source,deprecated:T.deprecated,description:T.description,resources:le&&le.length>0?le:void 0,assignableSubjectTypes:T.assignableSubjectTypes,recommendedSubjectTypes:T.recommendedSubjectTypes,attributes:o(T,d)}}}function Ji(T){if(T.scimName)return T.scimName;if(!T.name)return;let[_,...j]=T.name.split(" ");return{givenName:_,familyName:j.join(" ")||void 0}}function Hi(T){let _={attributes:o(T,A)};if(T.ecid!==void 0)_.ecid=T.ecid;if(T.accountClass!==void 0)_.accountClass=T.accountClass;return _.ecid!==void 0||_.accountClass!==void 0||_.attributes!==void 0?_:void 0}function Fi(T){return Object.keys(T.scimSchemaExtensions??{}).filter((_)=>_.startsWith("urn:")&&T.scimSchemaExtensions?.[_]!==void 0)}function Pr(T){let _=T.userName||T.email||T.id||"",j=T.emails??(T.email?[{value:T.email,primary:!0}]:[]),X=new Set([Gi]);if(T.scimEnterprise!==void 0)X.add(ys);let le=Hi(T);if(le!==void 0)X.add(u);for(let he of Fi(T))X.add(he);let ge={};if(T.scimEnterprise!==void 0)ge[ys]=T.scimEnterprise;if(le!==void 0)ge[u]=le;for(let[he,ke]of Object.entries(T.scimSchemaExtensions??{}))if(he.startsWith("urn:")&&he!==u&&ke!==void 0)ge[he]=ke;return{schemas:Array.from(X),id:T.id,externalId:T.externalId,userName:_,displayName:T.displayName??T.name??_,name:Ji(T),nickName:T.nickName,profileUrl:T.avatar,title:T.title,userType:T.userType,preferredLanguage:T.preferredLanguage,locale:T.locale,timezone:T.timezone,active:T.active??!0,emails:j,phoneNumbers:T.phoneNumbers,ims:T.ims,photos:T.photos,addresses:T.addresses,groups:T.groups,entitlements:T.entitlements,roles:T.roles,x509Certificates:T.x509Certificates,meta:{resourceType:"User",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()},...ge}}function Ur(T){return{schemas:[b],id:T.id,externalId:T.externalId,userName:T.clientId??T.id,displayName:T.displayName??T.clientId??T.id,description:T.description,active:T.active??!0,ecid:T.ecid,providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,v),meta:{resourceType:"Workload",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function Er(T){return{schemas:[C],id:T.id,externalId:T.externalId??T.id,userName:T.userName??T.email??T.id,displayName:T.displayName??T.name??T.userName??T.id,active:T.active??!0,emails:T.emails??(T.email?[{value:T.email,primary:!0}]:void 0),providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,I),meta:{resourceType:"Customer",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function fn(T){return{enabled:T?.enabled!==!1,assignment:T?.assignment??"app",delta:T?.delta}}var Yi="urn:ietf:params:scim:api:messages:2.0:ListResponse",jr="urn:ietf:params:scim:api:messages:2.0:Error",Lr="urn:ietf:params:scim:schemas:core:2.0:User",Mn="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Nr="urn:ietf:params:scim:schemas:core:2.0:Group",Xi="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",qn="urn:ietf:params:scim:schemas:core:2.0:ResourceType",on="urn:ietf:params:scim:schemas:core:2.0:Schema",Zi="00000000000000000000000000000000";function Qi(T){let _={timestamp:new Date().toISOString()};if(T)_.actor=T;try{let le=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),ge=le?.traceId;if(ge&&ge!==Zi){if(_.traceId=ge,le?.spanId)_.spanId=le.spanId}}catch{}return _}class On extends Error{constructor(T){super(T);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,On.prototype)}}async function Rs(T,_,j,X){let le=j.subjectType;if(!g.includes(le))throw new On(`Cannot grant ${j.targetType} "${n(j.target)}" to a "${le}" principal: only [${g.join(", ")}] principals are assignable on this platform.`);let ge=q(_,T);if(!ge&&!X)return;let he=n(j.target),ke;if(X)ke=await X.getNode(j.targetType,he);else if(ge)ke=await(j.targetType==="group"?ge.groups:j.targetType==="role"?ge.roles:ge.permissions).get(he);if(!ke)return;let ye=ke.assignableSubjectTypes;if(!ye||ye.length===0||!ye.includes(le))throw new On(`Cannot grant ${j.targetType} "${he}" to a "${le}" principal: this entitlement restricts assignment to [${(ye??[]).join(", ")||"none"}].`)}async function eo(T,_){let j=N(T.codeCatalog,n(_.target));if(!j)return;if(j.kind!==_.targetType)throw Error(`Cannot grant ${_.targetType} "${j.entity.id}": code declares that id as ${j.kind}.`);if(!T.catalogStore)throw Error(`Cannot grant code entitlement "${j.entity.id}": no AccessCatalogStore is wired for materialization.`);await K(j.kind,j.entity,L(T.catalogStore,j.kind))}async function to(T,_,j,X){await eo(T,_),await Rs(T.catalogStore,T.codeCatalog,_,X);let le={..._,status:_.status??"active",provenance:_.provenance??Qi()};if(le.id=p(le),await T.accessStore?.grant(le),T.accessIndex&&(T.catalogStore||T.codeCatalog)){let ge=await E(le,{catalog:T.catalogStore,code:T.codeCatalog,resources:T.resources,cache:X});await T.accessIndex.materialize(le.id,ge)}return j?.push({op:"add",change:le}),le}async function En(T,_,j){let X=_.id??p(_);await T.accessStore?.revoke(_),await T.accessIndex?.removeByRoot(X),j?.push({op:"delete",change:{..._,id:X}})}async function Gn(T,_){let j=await no(T,_),X=await so(T,_);return{oaa:j,delta:X}}async function no(T,_){if(_.length===0||!T.authz.oaa.isReady())return{status:"skipped"};return tn(T,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>T.authz.oaa.pushAccessChanges(_),{count:_.length})}async function tn(T,_,j,X,le){try{return await X(),{status:"ok"}}catch(ge){return T.log?.warn(j,{"ion.operation":_,"ion.outcome":"degraded",...le,error:Nt(ge)}),{status:"degraded",reason:Nt(ge)}}}var ro=6;async function so(T,_){let j=T.iamDelta;if(!j?.isReady()||_.length===0)return{status:"skipped"};let X=new Map;for(let ye of _){let fe=`${ye.change.subjectType}:${n(ye.change.subject)}\x00${ye.change.targetType}:${n(ye.change.target)}`;X.set(fe,ye)}let le=[...X.values()],ge=le.map(({op:ye,change:fe})=>()=>ye==="add"?j.onGrant(fe):j.onRevoke(fe)),ke=(await io(ge,ro)).filter((ye)=>ye.status==="rejected");if(ke.length>0)return T.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:ke.length,total:le.length,error:Nt(ke[0]?.reason)}),{status:"degraded",reason:Nt(ke[0]?.reason)};return{status:"ok"}}async function io(T,_){let j=Array(T.length),X=0,le=async()=>{while(!0){let he=X++;if(he>=T.length)return;let ke=T[he];if(!ke)continue;try{j[he]={status:"fulfilled",value:await ke()}}catch(ye){j[he]={status:"rejected",reason:ye}}}},ge=Array.from({length:Math.min(_,T.length)},le);return await Promise.all(ge),j}class Jn extends Error{constructor(T){super(T);this.name="DerivedRevokeError",Object.setPrototypeOf(this,Jn.prototype)}}class hn extends Error{constructor(T,_,j=!1){super(T);this.name="ScimMutationError",this.summary=_,this.clientError=j,Object.setPrototypeOf(this,hn.prototype)}}function Ke(T,_,j){return new Response(JSON.stringify({schemas:[jr],status:String(T),scimType:j,detail:_}),{status:T,headers:w})}function Kt(T,_){let j=_?.totalResults??T.length,X=_?.startIndex??1,le=_?.itemsPerPage??T.length;return new Response(JSON.stringify({schemas:[Yi],totalResults:j,startIndex:X,itemsPerPage:le,Resources:T}),{status:200,headers:w})}function St(T,_=200,j){let X=new Headers(w);if(j)X.set("Location",j);return new Response(JSON.stringify(T),{status:_,headers:X})}function hs(T){return Ke(T.clientError?409:500,`${T.message}; authz mutation summary: ${JSON.stringify(T.summary)}`,T.clientError?"mutability":"invalidValue")}function Dn(T){return p(T)}function Dr(T,_){return Kn(ks(T),ks(_))}function ks(T){let _=new Map;if(!T?.id)return _;for(let j of T.groups??[]){let X={subject:T.id,subjectType:"user",targetType:"group",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type}:void 0};_.set(Dn(X),X)}for(let j of T.roles??[]){let X={subject:T.id,subjectType:"user",targetType:"role",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}for(let j of T.entitlements??[]){let X={subject:T.id,subjectType:"user",targetType:"permission",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}return _}class Hn extends Error{constructor(T){super(T);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,Hn.prototype)}}function oo(T,_,j){if(T.type==="Group")return;if(T.type==="Workload")return"workload";if(T.type==="User")return"user";if(T.type==="Customer")return"customer";let X=_??[];if(X.length===1)return X[0];throw new Hn(`SCIM Group member "${T.value}" of entitlement "${j}" omits type, and the entitlement is assignable to more than one principal kind [${X.join(", ")||"none"}]. Set members[].type to User, Workload, or Customer.`)}function zn(T,_,j,X,le){let ge=new Map,he=X&&X.length>0?X:void 0;for(let ke of T??[]){let ye=oo(ke,le,j);if(!ye)continue;let fe={subject:ke.value,subjectType:ye,targetType:_,target:j,resources:he,metadata:ke.display||ke.type?{display:ke.display,type:ke.type}:void 0};ge.set(Dn(fe),fe)}return ge}function Ss(T){let _=T[e]?.resources;return _&&_.length>0?_:void 0}function ao(T,_){let j=(le,ge)=>[...le??[]].sort().join(",")===[...ge??[]].sort().join(","),X=T[e];if(X?.type!==void 0&&X.type!==_.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==_.entity.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,$r(_.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,_.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,_.entity.recommendedSubjectTypes))return!0;return!1}function co(T,_){let j=(ge,he)=>[...ge??[]].sort().join(",")===[...he??[]].sort().join(","),X=T[e],le=_[e];if(X?.type!==void 0&&X.type!==le?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==le?.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,le?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,le?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,le?.recommendedSubjectTypes))return!0;return!1}function uo(T){let _=new Map;for(let j of T)_.set(Dn(j),j);return _}async function an(T,_,j,X,le,ge){let he=[],ke=new Set,ye=(ze,Ye)=>`${Ye}\x00${ze}`,fe=ge?ge.get(`${j}:${X}`)??[]:_?(await _.listByTarget(j,X)).items:[];for(let ze of fe){let Ye=n(ze.subject),Qe=ze.metadata,ct=ze.subjectType==="workload"?"Workload":ze.subjectType==="customer"?"Customer":Qe?.type??"User",st=ye(Ye,ct);if(ke.has(st))continue;ke.add(st),he.push({value:Ye,...Qe?.display?{display:Qe.display}:{},type:ct})}for(let ze of le??[]){if(ze.targetType!==j||n(ze.target)!==X)continue;let Ye=n(ze.subject),Qe=ye(Ye,"Workload");if(ke.has(Qe))continue;ke.add(Qe),he.push({value:Ye,type:"Workload"})}if(j==="group"){let ze=await T.groups.get(X);for(let Ye of ze?.groups??[]){let Qe=n(Ye),ct=ye(Qe,"Group");if(!Qe||ke.has(ct))continue;ke.add(ct),he.push({value:Qe,type:"Group"})}}return he.length>0?he:void 0}function Kn(T,_){let j=[];for(let[X,le]of _)if(!T.has(X))j.push({action:"grant",change:le});for(let[X,le]of T)if(!_.has(X))j.push({action:"revoke",change:le});return j}async function Mr(T,_){if(T.oaa.isReady())await T.oaa.pushUser(_)}async function ws(T,_,j){if(_?.externalId&&_.externalId!==j.externalId)await T?.onUserDelete(_.externalId);await T?.onUserUpsert(j)}async function gn(T,_,j,X){let le={metadataApplied:!1,access:[]},ge={status:"skipped"},he=[],ke=new Q(T.catalogStore,T.resources,T.codeCatalog);try{try{await _(),le.metadataApplied=!0}catch(ye){for(let fe of j)le.access.push({change:fe.change,status:"rolled_back"});throw le.metadataApplied=!1,new hn(`SCIM metadata write failed: ${Nt(ye)}`,le,!1)}if(X?.oaa)await tn(T,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&T.iamDelta?.isReady())ge=await tn(T,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let ye=0;ye<j.length;ye++){let fe=j[ye];try{if(fe.action==="grant")await to(T,fe.change,he,ke);else await go(T,fe.change,he);le.access.push({change:fe.change,status:"applied"})}catch(ze){le.access.push({change:fe.change,status:"failed",error:ze});for(let Qe=ye+1;Qe<j.length;Qe++)le.access.push({change:j[Qe].change,status:"rolled_back"});let Ye=ze instanceof Jn||ze instanceof On;if(!Ye)await mo(T,fe.change,ke);throw new hn(Ye?Nt(ze):`SCIM access mutation failed: ${Nt(ze)}`,le,Ye)}}return le}finally{await po(T),le.egress=await Gn(T,he),le.egress.delta=lo(ge,le.egress.delta),fo(T,le)}}function lo(T,_){if(T.status==="degraded")return T;if(_.status==="degraded")return _;return T.status==="ok"||_.status==="ok"?{status:"ok"}:{status:"skipped"}}function Nt(T){return T instanceof Error?T.message:String(T)}async function po(T){try{await T.settleAuthz?.()}catch{}}async function mo(T,_,j){if(!T.accessIndex||!T.catalogStore&&!T.codeCatalog||!T.accessStore)return;let X=n(_.subject);if(!X)return;let le=_.subjectType;try{await pe(X,le,{accessStore:T.accessStore,accessIndex:T.accessIndex,catalogStore:T.catalogStore,code:T.codeCatalog,resources:T.resources},j)}catch(ge){T.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:le,error:Nt(ge)})}}function fo(T,_){if(!T.onAccessMutation)return;try{T.onAccessMutation(_)}catch{}}async function go(T,_,j){if(T.accessStore){let X=_.id??p(_);if(!await T.accessStore.get(X)){if((T.accessIndex?await T.accessIndex.has(_.subject,_.targetType,_.target,_.resources?.[0],_.subjectType):{allow:!1}).allow)throw new Jn(`Cannot revoke ${_.targetType} "${n(_.target)}" for "${n(_.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await En(T,_,j);return}}await En(T,_,j)}function yn(T){let _=T[e]?.type??"group";if(_==="group"||_==="role"||_==="permission")return _;throw Error(`Unsupported ionite SCIM Group authz type "${String(_)}"`)}async function Or(T,_,j){if(!T.oaa.isReady())return;if(j==="role"){await T.oaa.pushRole(_);return}if(j==="permission"){await T.oaa.pushPermission(_);return}await T.oaa.pushGroup(_)}function $r(T){let _=T.resources;if(!_||_.length===0)return;let j=_.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return j.length>0?j:void 0}function cn(T,_,j){return xr(T,_,j)}function yo(T,_){let j=T[e],le={...o(j?.attributes??{},d),id:_,name:T.displayName,displayName:T.displayName,description:j?.description??T.displayName,requestable:j?.requestable,riskLevel:j?.riskLevel??f,providerId:j?.providerId??T.externalId,requestUrl:j?.requestUrl,assignableSubjectTypes:["user"]};if(j?.resources!==void 0)le.resources=j.resources;return le}function ho(T){if(!T)return;let _=T.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!_)return;return{requestable:_[1]?.toLowerCase()==="true"}}function bs(T){if(!T)return;let _=T.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return _?_[1]:void 0}function ko(T){if(!T)return;let _=T.trim(),j=_.match(/^userName\s+eq\s+"([^"]*)"$/i);if(j)return{userName:j[1]};let X=_.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(X)return{externalId:X[1]};let le=_.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(le)return{updatedAfter:le[1]};return}function So(T,_,j){let X=new Set(["id","schemas"]),le={...T};if(_){let ge=new Set(_.split(",").map((he)=>he.trim()).filter(Boolean));for(let he of Object.keys(le))if(!X.has(he)&&!ge.has(he))delete le[he]}if(j){for(let ge of j.split(",").map((he)=>he.trim()).filter(Boolean))if(!X.has(ge))delete le[ge]}return le}function Cs(T,_){let j=async(ge,he,ke)=>{let ye=await T.toScim(ge),fe=ge.id;return{...ye,id:fe,meta:{...ye.meta??{},resourceType:T.resourceType,location:fe?yt(he,`${ke}/${encodeURIComponent(fe)}`):void 0}}},X=(ge,he)=>{let ke=he.op.toLowerCase();if(!he.path){if(ke!=="remove"&&he.value&&typeof he.value==="object"&&!Array.isArray(he.value))Object.assign(ge,he.value);return}if(ke==="remove"){delete ge[he.path];return}ge[he.path]=he.value};return{handler:async(ge,he)=>{if(!await _.validateAuth(ge))return Ke(401,"Authorization required");let ke=new URL(ge.url),ye=he?.basePath??`/${T.resourceType}s`,fe=ke.pathname;if(fe.startsWith(ye))fe=fe.substring(ye.length);let ze=fe.match(/^\/([^/]+)$/),Ye=ze?.[1]?decodeURIComponent(ze[1]):void 0,Qe=ke.searchParams.get("attributes"),ct=ke.searchParams.get("excludedAttributes"),st=(_e)=>So(_e,Qe,ct);try{if(Ye){if(ge.method==="GET"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);return St(st(await j(_e,ge,ye)))}if(ge.method==="PUT"||ge.method==="PATCH"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);let Le=await ge.json(),et=Le;if(ge.method==="PATCH"){let mt=Le.Operations;if(!Array.isArray(mt))return Ke(400,"PATCH requires Operations","invalidSyntax");let Rt=await T.toScim(_e);for(let Tt of mt)X(Rt,Tt);et=Rt}let De=await en(T.validator,et);if(De.issues)return Ke(400,De.issues.map((mt)=>mt.message).join("; "),"invalidValue");let it=ge.method==="PATCH"?"patch":"replace",pt=await T.store.upsert({...await T.fromScim(De.value,{existing:_e,mode:it}),id:_e.id??Ye});if(_e.active!==pt.active)await _.accessIndex?.setSubjectDisabled?.(pt.id,T.subjectType,pt.active===!1);let bt=pt.id?yt(ge,`${ye}/${encodeURIComponent(pt.id)}`):void 0;for(let mt of T.projections??[])await tn(_,`${mt.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM upsert; aggregation will reconcile`,()=>mt.upsert(pt,_e));return St(st(await j(pt,ge,ye)),200,bt)}if(ge.method==="DELETE"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);if(_.revokeSubjectAccess)await _.revokeSubjectAccess(Ye,T.subjectType);await T.store.delete(Ye),await _.accessIndex?.setSubjectDisabled?.(Ye,T.subjectType,!1);for(let Le of T.projections??[])await tn(_,`${Le.channel}.${T.subjectType}.delete`,`${T.resourceType} projection degraded after SCIM delete; aggregation will reconcile`,()=>Le.delete(_e));return new Response(null,{status:204})}return Ke(405,"Method not allowed")}if(ge.method==="GET"){let _e=parseInt(ke.searchParams.get("startIndex")??"",10),Le=parseInt(ke.searchParams.get("count")??"",10),et=_e!=null&&!Number.isNaN(_e)?Math.max(0,_e-1):0,De=Le!=null&&!Number.isNaN(Le)?Le:void 0,it=ko(ke.searchParams.get("filter"));if(it?.externalId!==void 0){let mt=T.store.getByExternalId?await T.store.getByExternalId(it.externalId):await T.store.lookup({externalId:it.externalId}),Rt=mt?[st(await j(mt,ge,ye))]:[];return Kt(Rt,{totalResults:Rt.length,startIndex:1,itemsPerPage:Rt.length})}let pt=await T.store.list({start:et,limit:De,filter:it}),bt=await Promise.all(pt.items.map(async(mt)=>st(await j(mt,ge,ye))));return Kt(bt,{totalResults:pt.total,startIndex:et+1,itemsPerPage:pt.count})}if(ge.method==="POST"){let _e=await ge.json(),Le=await en(T.validator,_e);if(Le.issues)return Ke(400,Le.issues.map((it)=>it.message).join("; "),"invalidValue");let et=await T.store.upsert(await T.fromScim(Le.value,{mode:"create"}));if(et.active===!1)await _.accessIndex?.setSubjectDisabled?.(et.id,T.subjectType,!0);for(let it of T.projections??[])await tn(_,`${it.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM create; aggregation will reconcile`,()=>it.upsert(et,void 0));let De=et.id?yt(ge,`${ye}/${encodeURIComponent(et.id)}`):void 0;return St(st(await j(et,ge,ye)),201,De)}return Ke(405,"Method not allowed")}catch(_e){if(M(_e))return Ke(409,_e.message,"uniqueness");return Ke(500,_e instanceof Error?_e.message:"Internal error")}}}}async function wo(T,_,j,X){let le=[],ge=[["group",T.groups],["role",T.roles],["permission",T.permissions]];for(let[ke,ye]of ge)for await(let fe of c((ze,Ye)=>ye.list({start:ze,limit:Ye,filter:{requestable:!0}})))if(fe.providerId===j)le.push({entity:fe,type:ke});if(le.length>1)throw new k(`Ambiguous providerId "${j}": ${le.length} entitlements share it (${le.map((ke)=>`${ke.type}:${ke.entity.id}`).join(", ")})`,"unique_violation","providerId");let he=le[0];if(he?.entity.requestable!==!0)return;return cn(he.entity,he.type,await an(T,_,he.type,he.entity.id,X))}async function bo(T,_,j,X){let le=Math.max(0,j.start),ge=j.limit!=null?le+j.limit:void 0,he={start:0,limit:ge,filter:j.filter},[ke,ye,fe]=await Promise.all([T.groups.list(he),T.roles.list(he),T.permissions.list(he)]),ze=[...ke.items.map((_e)=>({entity:_e,type:"group"})),...ye.items.map((_e)=>({entity:_e,type:"role"})),...fe.items.map((_e)=>({entity:_e,type:"permission"}))],Ye=ke.total+ye.total+fe.total,Qe=ze.slice(le,ge),ct=_?.listByTargets?await _.listByTargets(Qe.map(({entity:_e,type:Le})=>({targetType:Le,target:_e.id}))):void 0,st=await Promise.all(Qe.map(async({entity:_e,type:Le})=>cn(_e,Le,await an(T,_,Le,_e.id,X,ct))));return{resources:st,total:Ye,count:st.length}}async function Un(T,_,j,X){let[le,ge,he]=await Promise.all([T.groups.get(j),T.roles.get(j),T.permissions.get(j)]);if(le)return cn(le,"group",await an(T,_,"group",j,X));if(ge)return cn(ge,"role",await an(T,_,"role",j,X));if(he)return cn(he,"permission",await an(T,_,"permission",j,X));return}async function _r(T,_,j,X,le){let ge=yn(_),he=ge==="role"?await T.roles.get(j):ge==="permission"?await T.permissions.get(j):await T.groups.get(j),ke=yo(_,j),ye=he?.assignableSubjectTypes&&he.assignableSubjectTypes.length>0?he.assignableSubjectTypes:["user"],fe={...he??{},...ke,source:he?.source??"scim",assignableSubjectTypes:le?.assignableSubjectTypes??ye,recommendedSubjectTypes:le?.recommendedSubjectTypes??he?.recommendedSubjectTypes};if(le){if(delete fe.groups,delete fe.roles,delete fe.permissions,delete fe.resources,ge==="group")fe.groups=le.groups,fe.roles=le.roles,fe.permissions=le.permissions,fe.resources=le.resources;else if(ge==="role")fe.permissions=le.permissions}let ze=X?X.displayName??X.name:he?.name;if(ke.displayName===ze)delete fe.displayName;if(ke.riskLevel===(X?.riskLevel??f))delete fe.riskLevel;let Ye=o(ke,d),Qe=X?o(X,d):void 0;if(_[e]?.attributes!==void 0){for(let st of Object.keys(o(he??{},d)??{}))if(!(st in(Ye??{})))delete fe[st]}for(let[st,_e]of Object.entries(Ye??{}))if(S(_e,Qe?.[st]))delete fe[st];if(X)fe.name=X.name;let ct=ge==="role"?T.roles.set(fe):ge==="permission"?T.permissions.set(fe):T.groups.set(fe);return await ct.ready(),ct}async function Co(T,_){await Promise.all([T.groups.delete(_),T.roles.delete(_),T.permissions.delete(_)])}function Bn(){return crypto.randomUUID()}function en(T,_){let j=T;if(typeof j.validate==="function")return j.validate(_);return Promise.resolve(T["~standard"].validate(_))}function vo(T){if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}}function Lt(T){let _=vo(T);return _?R(_):void 0}function vs(...T){for(let _ of T){let j=Lt(_);if(!j)continue;for(let X of["/Users","/Groups","/Workloads","/Customers"])if(j.endsWith(X))return j.slice(0,-X.length)}return}function yt(T,_){return new URL(_,T.url).toString()}function Pe(T,_,j,X){let{multiValued:le=!1,...ge}=X??{};return{name:T,type:_,description:j,multiValued:le,...ge}}function Ro(T,_){return{schemas:[Xi],documentationUri:_?.documentationUri,patch:{supported:!0},bulk:{supported:!1},filter:{supported:!0,maxResults:1000},changePassword:{supported:!1},sort:{supported:!1},etag:{supported:!1},authenticationSchemes:[{type:"oauthbearertoken",name:"OAuth Bearer Token",description:"Use an ionite workload bearer token for IAM discovery and provisioning requests.",primary:!0}],meta:{resourceType:"ServiceProviderConfig",location:yt(T.request,`${T.basePath}/ServiceProviderConfig`)}}}function Ao(T){let _=[];if(T.supportsUsers)_.push({schemas:[qn],id:"User",name:"User",description:"User Account",endpoint:T.usersUrl,schema:Lr,schemaExtensions:[{schema:Mn,required:!1},{schema:u,required:!1}],meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/User`)}});if(T.supportsGroups)_.push({schemas:[qn],id:"Group",name:"Group",description:"Group",endpoint:T.groupsUrl,schema:Nr,schemaExtensions:[{schema:e,required:!1}],meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Group`)}});if(T.supportsWorkloads)_.push({schemas:[qn],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:T.workloadsUrl,schema:b,meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Workload`)}});if(T.supportsCustomers)_.push({schemas:[qn],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:T.customersUrl,schema:C,meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Customer`)}});return _}function Io(T){let _=[];if(T.supportsUsers)_.push({schemas:[on],id:Lr,name:"User",description:"User Account",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Lr)}`)},attributes:[Pe("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),Pe("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),Pe("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[Pe("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),Pe("familyName","string","The family name of the User.",{multiValued:!1}),Pe("givenName","string","The given name of the User.",{multiValued:!1}),Pe("middleName","string","The middle name(s) of the User.",{multiValued:!1}),Pe("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),Pe("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),Pe("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),Pe("nickName","string","The casual way to address the user.",{multiValued:!1}),Pe("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),Pe("title","string","The user title, such as Vice President.",{multiValued:!1}),Pe("userType","string","The relationship between the organization and the User.",{multiValued:!1}),Pe("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),Pe("locale","string","Default location for localizing values.",{multiValued:!1}),Pe("timezone","string","The User time zone.",{multiValued:!1}),Pe("active","boolean","The User administrative status.",{multiValued:!1}),Pe("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Email address value.",{multiValued:!1,required:!0}),Pe("display","string","Display label for the email.",{multiValued:!1}),Pe("type","string","Email type such as work or home.",{multiValued:!1}),Pe("primary","boolean","Primary email indicator.",{multiValued:!1})]}),Pe("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Phone number value.",{multiValued:!1,required:!0}),Pe("display","string","Display label for the phone number.",{multiValued:!1}),Pe("type","string","Phone number type.",{multiValued:!1}),Pe("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),Pe("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[Pe("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),Pe("display","string","Display label for the photo.",{multiValued:!1}),Pe("type","string","Photo type.",{multiValued:!1}),Pe("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),Pe("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[Pe("formatted","string","Formatted mailing address.",{multiValued:!1}),Pe("streetAddress","string","Full street address component.",{multiValued:!1}),Pe("locality","string","City or locality.",{multiValued:!1}),Pe("region","string","State or region.",{multiValued:!1}),Pe("postalCode","string","Postal code.",{multiValued:!1}),Pe("country","string","Country.",{multiValued:!1}),Pe("type","string","Address type.",{multiValued:!1}),Pe("primary","boolean","Primary address indicator.",{multiValued:!1})]}),Pe("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[Pe("value","string","Group identifier.",{multiValued:!1,required:!0}),Pe("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),Pe("display","string","Display name of the group.",{multiValued:!1}),Pe("type","string","Relationship type.",{multiValued:!1})]}),Pe("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Entitlement value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Entitlement type.",{multiValued:!1}),Pe("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),Pe("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Role value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Role type.",{multiValued:!1}),Pe("primary","boolean","Primary role indicator.",{multiValued:!1})]}),Pe("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[Pe("value","string","Certificate value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Certificate type.",{multiValued:!1}),Pe("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),_.push({schemas:[on],id:Mn,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Mn)}`)},attributes:[Pe("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),Pe("costCenter","string","Name of a cost center.",{multiValued:!1}),Pe("organization","string","Name of an organization.",{multiValued:!1}),Pe("division","string","Name of a division.",{multiValued:!1}),Pe("department","string","Name of a department.",{multiValued:!1}),Pe("manager","complex","The User manager.",{multiValued:!1,subAttributes:[Pe("value","string","Identifier of the manager User resource.",{multiValued:!1}),Pe("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),Pe("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),_.push({schemas:[on],id:u,name:"IoniteUser",description:"ionite User extension carrying ECID, account purpose, and AppDev custom attributes. See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(u)}`)},attributes:[Pe("ecid","string","Enterprise Controlled ID formatted as 'ecid:<realm>:<opaque>' (realm = the minting authority's id). Correlates multiple accounts to one identity.",{multiValued:!1,caseExact:!0}),Pe("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1}),Pe("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[on],id:e,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(e)}`)},attributes:[Pe("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),Pe("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),Pe("riskLevel","string",`Advisory access-risk classification. Unset values project as ${f}; canonical values are suggestions, not a closed enum.`,{multiValued:!1,required:!1,mutability:"readWrite",canonicalValues:[...Y]}),Pe("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),Pe("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),Pe("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),Pe("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),Pe("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),Pe("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),Pe("assignableSubjectTypes","string","AppDev-owned required audience of principal kinds (user, workload, customer) that may hold this entitlement. Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),Pe("recommendedSubjectTypes","string","AppDev advisory default principal kinds (subset of assignableSubjectTypes). Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),Pe("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[on],id:Nr,name:"Group",description:"Group",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Nr)}`)},attributes:[Pe("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),Pe("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),Pe("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[Pe("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),Pe("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),Pe("display","string","Display name of the member.",{multiValued:!1}),Pe("type","string","Member type.",{multiValued:!1})]})]});if(T.supportsWorkloads)_.push({schemas:[on],id:b,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(b)}`)},attributes:[Pe("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Pe("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),Pe("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),Pe("description","string","Free-form description of the Workload.",{multiValued:!1}),Pe("active","boolean","Administrative status of the Workload.",{multiValued:!1}),Pe("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsCustomers)_.push({schemas:[on],id:C,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(C)}`)},attributes:[Pe("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Pe("userName","string","Unique identifier typically used for login.",{multiValued:!1}),Pe("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),Pe("active","boolean","Administrative status of the Customer.",{multiValued:!1}),Pe("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[Pe("value","string","Email address.",{multiValued:!1,required:!0}),Pe("primary","boolean","Whether this is the primary email.",{multiValued:!1})]}),Pe("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});return _}function To(T,_,j,X,le,ge,he,ke,ye,fe,ze,Ye,Qe,ct,st,_e){let Le={authz:X,settleAuthz:_e,accessStore:le,accessIndex:ge,catalogStore:he,codeCatalog:ke,resources:ye,log:_,iamDelta:Ye,onAccessMutation:Qe,onInboundEntitlement:ct};if(!fe&&!ze)return;let De={...fe,...ze},it=De.users?.enabled!==!1,pt=De.groups?.enabled!==!1,bt=De.workloads?.enabled!==!1,mt=De.customers?.enabled!==!1;if(Boolean(De.url||De.userStore||he||ke)&&!j)_.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function Tt(){if(!j)throw _.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return j}async function Mt(Ve){let Xe=Tt(),Be=Ve.headers.get("Authorization");if(!Be?.startsWith("Bearer "))return!1;try{let Ze=Be.substring(7);return(await Xe.validateToken(Ze)).valid}catch{return!1}}async function kn(){let Ve=Tt(),Xe=typeof Ve.getServerToken==="function"?await Ve.getServerToken():await Ve.getToken();return new Headers({...w,...ae,Authorization:`Bearer ${Xe}`})}async function Jt(Ve,Xe,Be,Ze){if(!De.url)throw Error("IAM URL not configured for outgoing requests");let Je=`${De.url}${Xe}`;try{let He=await kn(),ut=await fetch(Je,{method:Ve,headers:He,body:Be?JSON.stringify(Be):void 0}),Ce=await a(ut,{log:_,operation:"scim.request"});if(!ut.ok)return{success:!1,error:Ce,status:ut.status};let me=await Ze["~standard"].validate(Ce);if(me.issues)return _.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:me.issues}),{success:!1,error:{schemas:[jr],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${me.issues.map((we)=>we.message).join("; ")}`},status:400};return{success:!0,data:me.value,status:ut.status}}catch(He){return{success:!1,error:{schemas:[jr],status:"500",detail:He instanceof Error?He.message:"Unknown error occurred"},status:500}}}function Sn(){return De.url}function un(Ve,Xe){let Be=Lt(Xe?.usersUrl??De.usersUrl??"/api/iam/Users")??"/api/iam/Users",Ze=Lt(Xe?.groupsUrl??De.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Je=Lt(Xe?.workloadsUrl??De.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",He=Lt(Xe?.customersUrl??De.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",ut=Lt(Xe?.discovery?.basePath??De.discovery?.basePath)??vs(Be,Ze,Je,He);if(!ut)return;return{request:Ve,basePath:ut,usersUrl:Be,groupsUrl:Ze,workloadsUrl:Je,customersUrl:He,supportsUsers:it&&Boolean(De.userStore),supportsGroups:pt&&Boolean(he||ke),supportsWorkloads:bt&&Boolean(De.workloadIdentityStore),supportsCustomers:mt&&Boolean(De.customerStore)}}async function Ht(Ve){let Xe=Ro(Ve,De.discovery);return await De.discovery?.buildServiceProviderConfig?.(Ve,Xe)??Xe}async function Ft(Ve){let Xe=Ao(Ve);return await De.discovery?.buildResourceTypes?.(Ve,Xe)??Xe}async function nn(Ve){let Xe=Io(Ve);return await De.discovery?.buildSchemas?.(Ve,Xe)??Xe}async function dn(Ve,Xe){let Be=un(Ve,Xe);if(!Be)return;let Ze=R(new URL(Ve.url).pathname),{basePath:Je}=Be;if(Ze!==Je&&!Ze.startsWith(`${Je}/`))return;let He=R(Ze.slice(Je.length)||"/");if(!(He==="/ServiceProviderConfig"||He==="/ResourceTypes"||He.startsWith("/ResourceTypes/")||He==="/Schemas"||He.startsWith("/Schemas/")))return;if(Ve.method!=="GET")return Ke(405,"Method not allowed");if(!await Mt(Ve))return Ke(401,"Authorization required");if(He==="/ServiceProviderConfig")return St(await Ht(Be));if(He==="/ResourceTypes")return Kt(await Ft(Be));if(He.startsWith("/ResourceTypes/")){let me=decodeURIComponent(He.slice(15)),we=(await Ft(Be)).find((be)=>be.id===me||be.name===me);return we?St(we):Ke(404,"Resource not found")}if(He==="/Schemas")return Kt(await nn(Be));if(He.startsWith("/Schemas/")){let me=decodeURIComponent(He.slice(9)),we=(await nn(Be)).find((be)=>be.id===me);return we?St(we):Ke(404,"Resource not found")}return}let xt,ln;if(De.url)ln=async(Xe,Be)=>{let Ze={...Xe,schemas:Xe.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return Jt("POST","/Users",Ze,T.user)},xt={createGroup:async(Xe,Be)=>{let Ze={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:Xe,externalId:Be?.id,members:Be?.members};return Jt("POST","/Groups",Ze,T.group)}};let Yt;if(he||ke){let Ve=q(ke,he),Xe=(Ae,Se,ve)=>{let Ie=Ae[e]??{},Te=yn(Ae),xe=Ae.id,Ne=xe?yt(Se,`${ve}/${encodeURIComponent(xe)}`):void 0,Oe={id:xe??Ae.externalId??Ae.displayName,name:Ae.displayName,displayName:Ae.displayName,description:Ie.description??Ae.displayName,requestable:Ie.requestable,providerId:Ie.providerId??Ae.externalId,requestUrl:Ie.requestUrl,source:Ie.source,deprecated:Ie.deprecated,riskLevel:Ie.riskLevel,assignableSubjectTypes:Ie.assignableSubjectTypes,recommendedSubjectTypes:Ie.recommendedSubjectTypes},Ge=Ie.requestUrl??De.entitlementRequestUrl?.(Oe,Te,{request:Se});return{...Ae,meta:{...Ae.meta,resourceType:"Group",location:Ne},[e]:{...Ie,requestUrl:Ge}}},Be=(Ae)=>N(ke,Ae),Ze=async(Ae,Se)=>{if(!he){if(Se)throw Error(`Cannot persist access for code entitlement "${Ae.entity.id}": no AccessCatalogStore is wired.`);return Ae.entity}try{return await K(Ae.kind,Ae.entity,L(he,Ae.kind))}catch(ve){if(Se)throw ve;return _.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:Ae.entity.id,entitlementType:Ae.kind,error:Nt(ve)}),Ae.entity}},Je=async(Ae)=>{if(!he)return;try{await Z(ke,he,Ae)}catch(Se){_.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:Ae,error:Nt(Se)})}},He=(Ae,Se)=>Ke(403,`Entitlement "${Ae}" is declared in application code; its structural definition cannot be ${Se} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),ut=(Ae)=>Ae.path==="members"||Boolean(Ae.path?.startsWith("members[")),Ce=(Ae)=>ut(Ae)||Ae.path==="displayName"||Ae.path===`${e}.description`||Ae.path===`${e}.riskLevel`||Ae.path===`${e}.providerId`||Ae.path===`${e}.requestUrl`||Ae.path===`${e}.attributes`||Boolean(Ae.path?.startsWith(`${e}.attributes.`)),me=(Ae)=>Ae?.[e]?.requestable===!0,we=(Ae)=>Ke(404,`Requestable Group ${Ae} not found`,"invalidValue"),be=async(Ae,Se)=>{if(!await Mt(Ae))return Ke(401,"Authorization required");let Ie=new URL(Ae.url),Te=Se?.basePath??"/Groups",xe=Ie.pathname;if(xe.startsWith(Te))xe=xe.substring(Te.length);let Oe=xe.match(/^\/([^/]+)$/)?.[1],Ge=Ae.method;try{if(Oe)switch(Ge){case"GET":return await Ue(Ae,Te,Oe);case"PUT":return await We(Ae,Te,Oe);case"PATCH":return await qe(Ae,Te,Oe);case"DELETE":return await Ee(Oe);default:return Ke(405,"Method not allowed")}else if(xe===""||xe==="/")switch(Ge){case"GET":return await Re(Ae,Te);case"POST":return await je(Ae,Te);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(Fe){if(Fe instanceof hn)return hs(Fe);if(Fe instanceof Hn)return Ke(400,Fe.message,"invalidValue");if(M(Fe))return Ke(409,Fe.message,"uniqueness");return _.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},Fe),Ke(500,Fe instanceof Error?Fe.message:"Internal server error")}},Re=async(Ae,Se)=>{let ve=new URL(Ae.url),Ie=ve.searchParams.get("startIndex"),Te=ve.searchParams.get("count"),xe=Ie!=null?parseInt(Ie,10):void 0,Ne=Te!=null?parseInt(Te,10):void 0,Oe=xe!=null&&!Number.isNaN(xe)?Math.max(0,xe-1):0,Ge=Ne!=null&&!Number.isNaN(Ne)?Ne:void 0,Fe=ve.searchParams.get("filter"),rt=bs(Fe);if(rt!==void 0){await Je();let nt=await wo(Ve,le,rt,st),ht=nt?[Xe(nt,Ae,Se)]:[];return Kt(ht,{totalResults:ht.length,startIndex:1,itemsPerPage:ht.length})}if(ho(Fe)?.requestable===!1)return Kt([],{totalResults:0,startIndex:1,itemsPerPage:0});let ft={requestable:!0};if(ke)await Promise.all([...ke.groups.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"group"})),...ke.roles.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"role"})),...ke.permissions.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"permission"}))].map((nt)=>Ze(nt,!1)));await Je();let dt=await bo(Ve,le,{start:Oe,limit:Ge,filter:ft},st);return Kt(dt.resources.map((nt)=>Xe(nt,Ae,Se)),{totalResults:dt.total,startIndex:Oe+1,itemsPerPage:dt.count})},Ue=async(Ae,Se,ve)=>{let Ie=Be(ve);if(Ie&&Ie.entity.requestable!==!0)return we(ve);if(Ie)await Ze(Ie,!1);await Je(ve);let Te=await Un(Ve,le,ve,st);if(!me(Te))return we(ve);return St(Xe(Te,Ae,Se))},je=async(Ae,Se)=>{let ve=await Ae.json(),Ie=await en(T.group,ve);if(Ie.issues)return _.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:Ie.issues}),Ke(400,`Request validation failed: ${Ie.issues.map((Dt)=>Dt.message).join("; ")}`,"invalidValue");let Te=Ie.value;if(!Te.displayName)return Ke(400,"displayName is required","invalidValue");if(Te[e]?.requestable===!1)return Ke(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(Te[e]={...Te[e],requestable:!0},!Le.onInboundEntitlement)return Ke(501,"IAM-sourced entitlement creation is not implemented: this application declares no authz.onInboundEntitlement callback.","invalidValue");if(!he)return Ke(501,"Group creation is not supported: this application declares its catalog in code (authz.catalog) and wires no AccessCatalogStore for SCIM-authored definitions.","invalidValue");let Ne=yn(Te),Oe=Te[e],Ge=await Le.onInboundEntitlement({type:Ne,displayName:Te.displayName,description:Oe?.description,externalId:Te.externalId,riskLevel:Oe?.riskLevel,attributes:Oe?.attributes,resources:Oe?.resources,members:Te.members??[],request:Ae});if(!Ge.accept)return Ke(403,Ge.reason??"The application rejected the IAM-sourced entitlement");if((Ne==="role"?[...Ge.groups??[],...Ge.roles??[],...Ge.resources??[]]:Ne==="permission"?[...Ge.groups??[],...Ge.roles??[],...Ge.permissions??[],...Ge.resources??[]]:[]).length>0)throw Error(`onInboundEntitlement returned structure that is invalid for entitlement type "${Ne}".`);let rt=Ge.assignableSubjectTypes??["user"];x({id:Ge.id,assignableSubjectTypes:rt,recommendedSubjectTypes:Ge.recommendedSubjectTypes});let at=async(Dt,vt)=>{await Promise.all((vt??[]).map(async(qt)=>{if(!(Dt==="group"?await Ve.groups.get(qt):Dt==="role"?await Ve.roles.get(qt):Dt==="permission"?await Ve.permissions.get(qt):await ye?.get(qt)))throw Error(`onInboundEntitlement accepted "${Te.displayName}" with unknown ${Dt} binding "${qt}".`)}))};await Promise.all([at("group",Ge.groups),at("role",Ge.roles),at("permission",Ge.permissions),at("resource",Ge.resources)]);let ft=Ge.id??Bn(),[dt,nt,ht]=await Promise.all([Ve.groups.get(ft),Ve.roles.get(ft),Ve.permissions.get(ft)]);if(dt||nt||ht)throw new k(`id "${ft}" already exists in the entitlement catalog`,"unique_violation","id");let tt=Ge.resources,Ut=Kn(new Map,zn(Te.members,Ne,ft,tt,rt)),Et;await gn(Le,async()=>{Et=await _r(Ve,Te,ft,void 0,{...Ge,assignableSubjectTypes:rt})},Ut,{oaa:()=>Or(X,Et,Ne)});let Ct=await an(Ve,le,Ne,ft),Vt=Xe(cn(Et,Ne,Ct),Ae,Se);return St(Vt,201,Vt.meta?.location)},We=async(Ae,Se,ve)=>{let Ie=await Ae.json(),Te=await en(T.group,Ie);if(Te.issues)return _.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:Te.issues}),Ke(400,`Request validation failed: ${Te.issues.map((ht)=>ht.message).join("; ")}`,"invalidValue");let xe=Te.value,Ne=yn(xe),Oe=Be(ve);if(Oe&&Oe.entity.requestable!==!0)return we(ve);if(Oe){if(await Ze(Oe,!0),ao(xe,Oe))return He(ve,"replaced")}let Ge=await Un(Ve,le,ve);if(!me(Ge))return we(ve);if(!Oe&&Ge[e]?.source==="code"&&co(xe,Ge))return He(ve,"replaced");let Fe=Oe?.kind??Ne,rt=Oe?$r(Oe.entity):Ss(xe),at=le?(await le.listByTarget(Fe,ve)).items:[],ft=Kn(uo(at),zn(xe.members,Fe,ve,rt,Oe?.entity.assignableSubjectTypes??Ge[e]?.assignableSubjectTypes??xe[e]?.assignableSubjectTypes)),dt;await gn(Le,async()=>{dt=await _r(Ve,xe,ve,Oe?.entity)},ft,{oaa:()=>Or(X,dt,Fe)});let nt=await an(Ve,le,Fe,ve);return St(Xe(cn(dt,Fe,nt),Ae,Se))},qe=async(Ae,Se,ve)=>{let Ie=Be(ve);if(Ie&&Ie.entity.requestable!==!0)return we(ve);if(Ie)await Ze(Ie,!0);let Te=await Un(Ve,le,ve);if(!me(Te))return we(ve);let xe=await Ae.json();if((Ie!==void 0||Te[e]?.source==="code")&&(xe.Operations??[]).some((tt)=>!Ce(tt)))return He(ve,"patched");let Oe={...Te};for(let tt of xe.Operations??[])if(tt.op==="replace"&&tt.path&&tt.value!==void 0){if(tt.path==="displayName")Oe.displayName=tt.value;else if(tt.path===`${e}.requestable`)Oe[e]={...Oe[e],requestable:Boolean(tt.value)};else if(tt.path===`${e}.description`)Oe[e]={...Oe[e],description:String(tt.value)};else if(tt.path===`${e}.riskLevel`)Oe[e]={...Oe[e],riskLevel:String(tt.value)};else if(tt.path===`${e}.providerId`)Oe[e]={...Oe[e],providerId:String(tt.value)};else if(tt.path===`${e}.requestUrl`)Oe[e]={...Oe[e],requestUrl:String(tt.value)};else if(tt.path===`${e}.attributes`&&typeof tt.value==="object"&&tt.value!==null&&!Array.isArray(tt.value))Oe[e]={...Oe[e],attributes:tt.value};else if(tt.path.startsWith(`${e}.attributes.`)){let Ut=tt.path.slice(`${e}.attributes.`.length);Oe[e]={...Oe[e],attributes:{...Oe[e]?.attributes,[Ut]:tt.value}}}}else if(tt.op==="add"&&tt.path==="members"&&tt.value!==void 0){let Ut=tt.value;Oe.members=[...Oe.members??[],...Ut]}else if(tt.op==="remove"&&tt.path?.startsWith("members[")){let Ut=tt.path.match(/members\[value eq "([^"]+)"\]/);if(Ut)Oe.members=(Oe.members??[]).filter((Et)=>Et.value!==Ut[1])}else if(tt.op==="remove"&&tt.path?.startsWith(`${e}.attributes.`)){let Ut=tt.path.slice(`${e}.attributes.`.length),Et={...Oe[e]?.attributes};delete Et[Ut],Oe[e]={...Oe[e],attributes:Et}}let Ge=await en(T.group,Oe);if(Ge.issues)return _.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:Ge.issues}),Ke(400,`Request validation failed: ${Ge.issues.map((tt)=>tt.message).join("; ")}`,"invalidValue");let Fe=Ie?.kind??yn(Oe),rt=Ie?$r(Ie.entity):Ss(Oe),at=Ie?.entity.assignableSubjectTypes??Te[e]?.assignableSubjectTypes??Oe[e]?.assignableSubjectTypes,ft=Kn(zn(Te.members,Fe,ve,rt,at),zn(Oe.members,Fe,ve,rt,at)),dt,nt=!Ie||(xe.Operations??[]).some((tt)=>!ut(tt));await gn(Le,async()=>{if(nt)dt=await _r(Ve,Oe,ve,Ie?.entity)},ft,nt?{oaa:()=>Or(X,dt,Fe)}:void 0);let ht=await Un(Ve,le,ve);return St(Xe(ht,Ae,Se))},Ee=async(Ae)=>{let Se=Be(Ae);if(Se&&Se.entity.requestable!==!0)return we(Ae);if(Se)await Ze(Se,!0);let ve=await Un(Ve,le,Ae);if(!me(ve))return we(Ae);let Ie=ve[e];if((Se||Ie?.source==="code")&&Ie?.deprecated!==!0)return Ke(403,`Code-owned entitlement "${Ae}" can be deleted only after it is marked deprecated.`,"mutability");let Te=yn(ve);if(le){let xe=await le.listByTarget(Te,Ae),Ne=[];for(let Oe of xe.items)await En(Le,Oe,Ne);await Gn(Le,Ne)}return await Co(Ve,Ae),new Response(null,{status:204})};Yt={handler:be}}let Pt,At,$t;if(De.userStore){let{userStore:Ve,inboundUsers:Xe}=De,Be=(Se)=>Se?.find((ve)=>ve.primary)?.value||Se?.[0]?.value,Ze=async(Se)=>{if(Xe?.mapBaseUserToScim)return await Xe.mapBaseUserToScim(Se);return Pr(Se)},Je=async(Se,ve,Ie)=>{let Te=await Ze(Se),xe=Te.id??Se.id;return{...Te,id:xe,meta:{...Te.meta,resourceType:"User",location:xe?yt(ve,`${Ie}/${encodeURIComponent(xe)}`):void 0}}},He=async(Se,ve)=>{if(Xe?.mapValidatedScimToBaseUser)return await Xe.mapValidatedScimToBaseUser(Se,ve);let Ie=new Date,Te=Be(Se.emails),xe=Se.name?.formatted||[Se.name?.givenName,Se.name?.middleName,Se.name?.familyName].filter(Boolean).join(" ").trim()||Se.displayName,Ne=Se.id||ve.existing?.id||Bn(),Oe=Se.userName||Te||ve.existing?.userName||Ne,Ge=xe||Se.displayName||ve.existing?.name||Oe,Fe=Object.fromEntries(Object.entries(Se).filter(([ht,tt])=>ht.startsWith("urn:")&&ht!==Mn&&ht!==u&&tt!==void 0)),rt=Se[u],at=o(rt?.attributes??{},A),ft=rt?.ecid!==void 0&&rt.ecid!==null?O(rt.ecid):ve.existing?.ecid,dt=rt?.accountClass??ve.existing?.accountClass,nt=ve.existing?.sso;return{...ve.existing??{},id:Ne,userName:Oe,name:Ge,email:Te||ve.existing?.email||Oe,avatar:Se.profileUrl,sso:{...nt??{},profile:{...nt?.profile??{},sub:Ne,iss:nt?.profile.iss??"iam-provisioned",aud:nt?.profile.aud??"iam-provisioned",exp:nt?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:nt?.profile.iat??Math.floor(Date.now()/1000),email:Te||ve.existing?.email||Oe,email_verified:!0,name:Ge,preferred_username:Oe},tenant:nt?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:nt?.scope??"openid profile email",tokenType:nt?.tokenType??"Bearer",expires:nt?.expires??new Date(Date.now()+3600000)},externalId:Se.externalId,ecid:ft,accountClass:dt,displayName:Se.displayName,scimName:Se.name,emails:Se.emails,nickName:Se.nickName,title:Se.title,preferredLanguage:Se.preferredLanguage,locale:Se.locale,timezone:Se.timezone,active:Se.active,phoneNumbers:Se.phoneNumbers,ims:Se.ims,photos:Se.photos,addresses:Se.addresses,groups:Se.groups,entitlements:Se.entitlements,roles:Se.roles,x509Certificates:Se.x509Certificates,scimEnterprise:Se[Mn],scimSchemaExtensions:Object.keys(Fe).length>0?Fe:void 0,createdAt:ve.existing?.createdAt??(Se.meta?.created?new Date(Se.meta.created):Ie),updatedAt:Se.meta?.lastModified?new Date(Se.meta.lastModified):Ie,userType:Se.userType,...at}},ut=(Se,ve,Ie)=>{Se[ve]=Ie},Ce=(Se,ve,Ie)=>{let Te=Se[ve];if(Array.isArray(Te)){Se[ve]=[...Te,...Array.isArray(Ie)?Ie:[Ie]];return}if(Te&&typeof Te==="object"&&!Array.isArray(Te)&&Ie&&typeof Ie==="object"&&!Array.isArray(Ie)){Se[ve]={...Te,...Ie};return}Se[ve]=Ie},me=(Se,ve,Ie)=>{let Te=ve.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),xe=Te?[Te[1],...Te[2]?.split(":")??[]]:ve.split("."),Ne=Se;for(let Ge of xe.slice(0,-1)){let Fe=Ne[Ge];if(Fe===void 0){if(!Ie)return null;Ne[Ge]={}}else if(Fe===null||typeof Fe!=="object"||Array.isArray(Fe)){if(!Ie)return null;Ne[Ge]={}}Ne=Ne[Ge]}let Oe=xe.at(-1);if(!Oe)return null;return{parent:Ne,key:Oe}},we=(Se,ve)=>{let Ie=ve.op.toLowerCase();if(!ve.path){if(Ie!=="remove"&&ve.value&&typeof ve.value==="object"&&!Array.isArray(ve.value))Object.assign(Se,ve.value);return}let Te=ve.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(Te&&Ie==="remove"){let[,Ne,Oe]=Te,Ge=Se[Ne];if(Array.isArray(Ge))Se[Ne]=Ge.filter((Fe)=>!(Fe&&typeof Fe==="object"&&("value"in Fe)&&Fe.value===Oe));return}let xe=me(Se,ve.path,Ie!=="remove");if(!xe)return;if(Ie==="remove"){delete xe.parent[xe.key];return}if(Ie==="add"){Ce(xe.parent,xe.key,ve.value);return}ut(xe.parent,xe.key,ve.value)},be=async(Se,ve)=>{if(!await Mt(Se))return Ke(401,"Authorization required");let Te=new URL(Se.url),xe=ve?.basePath??"/Users",Ne=Te.pathname;if(Ne.startsWith(xe))Ne=Ne.substring(xe.length);let Ge=Ne.match(/^\/([^/]+)$/)?.[1],Fe=Se.method;try{if(Ge)switch(Fe){case"GET":return await Ue(Se,xe,Ge);case"PUT":return await qe(Se,xe,Ge);case"PATCH":return await Ee(Se,xe,Ge);case"DELETE":return await Ae(Ge);default:return Ke(405,"Method not allowed")}else if(Ne===""||Ne==="/")switch(Fe){case"GET":return await Re(Se,xe);case"POST":return await We(Se,xe);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(rt){if(rt instanceof hn)return hs(rt);if(M(rt))return Ke(409,rt.message,"uniqueness");return _.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},rt),Ke(500,rt instanceof Error?rt.message:"Internal server error")}},Re=async(Se,ve)=>{let Ie=new URL(Se.url),Te=Ie.searchParams.get("startIndex"),xe=Ie.searchParams.get("count"),Ne=Te!=null?parseInt(Te,10):void 0,Oe=xe!=null?parseInt(xe,10):void 0,Ge=Ne!=null&&!Number.isNaN(Ne)?Math.max(0,Ne-1):0,Fe=Oe!=null&&!Number.isNaN(Oe)?Oe:void 0,rt=bs(Ie.searchParams.get("filter"));if(rt!==void 0){let dt=await Ve.lookup({externalId:rt}),nt=dt?[await Je(dt,Se,ve)]:[];return Kt(nt,{totalResults:nt.length,startIndex:1,itemsPerPage:nt.length})}let at=await Ve.list({start:Ge,limit:Fe}),ft=await Promise.all(at.items.map((dt)=>Je(dt,Se,ve)));return Kt(ft,{totalResults:at.total,startIndex:Ge+1,itemsPerPage:at.count})},Ue=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");return St(await Je(Te,Se,ve))},je=async(Se,ve)=>{let Ie=Le.accessIndex;if(!Ie?.setSubjectDisabled||!ve.id)return;let Te=Se?Se.active??!0:!0,xe=ve.active??!0;if(Se&&Te===xe)return;if(!Se&&xe)return;await Ie.setSubjectDisabled(ve.id,"user",!xe)},We=async(Se,ve)=>{let Ie=await Se.json(),Te=await en(T.user,Ie);if(Te.issues)return _.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:Te.issues}),Ke(400,`Request validation failed: ${Te.issues.map((Ge)=>Ge.message).join("; ")}`,"invalidValue");let xe=Te.value;if(!xe.userName&&!xe.emails?.[0]?.value)return Ke(400,"userName or email is required","invalidValue");let Ne=await He(xe,{mode:"create"});await gn(Le,async()=>{await Ve.upsert(Ne),await je(void 0,Ne)},Dr(void 0,Ne),{oaa:async()=>{await Mr(X,Ne)},delta:async()=>{await Le.iamDelta?.onUserUpsert(Ne)}});let Oe=await Je(Ne,Se,ve);return St(Oe,201,Oe.meta?.location)},qe=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");let xe=await Se.json(),Ne=await en(T.user,xe);if(Ne.issues)return _.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:Ne.issues}),Ke(400,`Request validation failed: ${Ne.issues.map((Fe)=>Fe.message).join("; ")}`,"invalidValue");let Oe=Ne.value,Ge=await He({...Oe,id:Ie},{existing:Te,mode:"replace"});return Ge.createdAt=Te.createdAt,Ge.updatedAt=new Date,await gn(Le,async()=>{await Ve.upsert(Ge),await je(Te,Ge)},Dr(Te,Ge),{oaa:async()=>{await Mr(X,Ge)},delta:async()=>{await ws(Le.iamDelta,Te,Ge)}}),St(await Je(Ge,Se,ve))},Ee=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");let Ne=(await Se.json()).Operations??[],Ge={...await Ze(Te)};for(let at of Ne)we(Ge,at);let Fe=await en(T.user,Ge);if(Fe.issues)return _.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:Fe.issues}),Ke(400,`Request validation failed: ${Fe.issues.map((at)=>at.message).join("; ")}`,"invalidValue");let rt=await He(Fe.value,{existing:Te,mode:"patch"});return rt.updatedAt=new Date,await gn(Le,async()=>{await Ve.upsert(rt),await je(Te,rt)},Dr(Te,rt),{oaa:async()=>{await Mr(X,rt)},delta:async()=>{await ws(Le.iamDelta,Te,rt)}}),St(await Je(rt,Se,ve))},Ae=async(Se)=>{let ve=await Ve.get(Se);if(!ve)return Ke(404,`User ${Se} not found`,"invalidValue");if(le){let Ie=[];for await(let Te of c((xe,Ne)=>le.listBySubject(Se,"user",{start:xe,limit:Ne})))await En(Le,Te,Ie);await Gn(Le,Ie)}if(await Ve.delete(Se),await Le.accessIndex?.setSubjectDisabled?.(Se,"user",!1),ve.externalId&&Le.iamDelta?.isReady())await tn(Le,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>Le.iamDelta?.onUserDelete(ve.externalId)??Promise.resolve(),{id:Se,kind:"user"});else if(Le.iamDelta?.isReady())Le.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:Se,kind:"user"});if(Le.authz.oaa.isReady())await tn(Le,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>Le.authz.oaa.deleteUser(Se),{id:Se,kind:"user"});return new Response(null,{status:204})};Pt={handler:be}}let Wt=async(Ve,Xe)=>{if(!le)return;let Be=[];for await(let Ze of c((Je,He)=>le.listBySubject(Ve,Xe,{start:Je,limit:He})))await En(Le,Ze,Be);await Gn(Le,Be)};if(De.workloadIdentityStore){let{workloadIdentityStore:Ve,inboundWorkloads:Xe}=De;At=Cs({resourceType:"Workload",subjectType:"workload",store:Ve,validator:T.workload??ue,toScim:async(Be)=>await(Xe?.mapBaseWorkloadToScim?.(Be)??Ur(Be)),fromScim:async(Be,Ze)=>{if(Xe?.mapValidatedScimToBaseWorkload)return Xe.mapValidatedScimToBaseWorkload(Be,Ze);let Je=Ze.existing,He=Be,ut=He.id?.trim()||Je?.id||Bn(),Ce=o(He.attributes??{},v);return{...Je??{},id:ut,externalId:He.externalId??Je?.externalId,clientId:He.userName??Je?.clientId??ut,displayName:He.displayName??Je?.displayName,description:He.description??Je?.description,active:He.active??Je?.active??!0,providerId:Je?.providerId,requestUrl:Je?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Be)=>{if(X.oaa.isReady())await X.oaa.pushWorkload(Be)},delete:async(Be)=>{if(X.oaa.isReady())await X.oaa.deleteWorkload(Be.id)}},{channel:"delta",upsert:async(Be,Ze)=>{let Je=Ze?.externalId??Ze?.id,He=Be.externalId??Be.id;if(Je&&Je!==He)await Ye?.onWorkloadDelete(Je);await Ye?.onWorkloadUpsert(Be)},delete:async(Be)=>{await Ye?.onWorkloadDelete(Be.externalId??Be.id)}}]},{validateAuth:Mt,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}if(De.customerStore){let{customerStore:Ve,inboundCustomers:Xe}=De;$t=Cs({resourceType:"Customer",subjectType:"customer",store:Ve,validator:T.customer??de,toScim:async(Be)=>await(Xe?.mapBaseCustomerToScim?.(Be)??Er(Be)),fromScim:async(Be,Ze)=>{if(Xe?.mapValidatedScimToBaseCustomer)return Xe.mapValidatedScimToBaseCustomer(Be,Ze);let Je=Ze.existing,He=Be,ut=He.id?.trim()||Je?.id||Bn(),Ce=o(He.attributes??{},I),me=He.emails?.find((we)=>we.primary)?.value??He.emails?.[0]?.value;return{...Je??{},id:ut,externalId:He.externalId??Je?.externalId??ut,userName:He.userName??Je?.userName??ut,name:He.displayName??Je?.name??He.userName??ut,email:me??Je?.email??"",displayName:He.displayName??Je?.displayName,emails:He.emails??Je?.emails,active:He.active??Je?.active??!0,providerId:Je?.providerId,requestUrl:Je?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Be)=>{if(X.oaa.isReady())await X.oaa.pushCustomer(Be)},delete:async(Be)=>{if(X.oaa.isReady()&&Be.id)await X.oaa.deleteCustomer(Be.id)}},{channel:"delta",upsert:async(Be,Ze)=>{let Je=Ze?.externalId??Ze?.id,He=Be.externalId??Be.id;if(Je&&Je!==He)await Ye?.onCustomerDelete(Je);await Ye?.onCustomerUpsert(Be)},delete:async(Be)=>{let Ze=Be.externalId??Be.id;if(Ze)await Ye?.onCustomerDelete(Ze)}}]},{validateAuth:Mt,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}async function rn(Ve,Xe){Tt();let Be=new URL(Ve.url).pathname,Ze=Lt(Xe?.usersUrl??De.usersUrl??"/api/iam/Users")??"/api/iam/Users",Je=Lt(Xe?.groupsUrl??De.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",He=Lt(Xe?.workloadsUrl??De.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",ut=Lt(Xe?.customersUrl??De.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",Ce=`${vs(Ze,Je,He,ut)??"/api/iam"}/AccessRequests`,me=await dn(Ve,Xe);if(me)return me;let we=(be)=>Be===be||Be.startsWith(`${be}/`);if(we(Ze)){if(!it)return Ke(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!Pt)return Ke(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return Pt.handler(Ve,{basePath:Ze})}if(we(Je)){if(!pt)return Ke(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!Yt)return Ke(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return Yt.handler(Ve,{basePath:Je})}if(we(He)){if(!bt)return Ke(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!At)return Ke(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return At.handler(Ve,{basePath:He})}if(we(ut)){if(!mt)return Ke(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!$t)return Ke(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return $t.handler(Ve,{basePath:ut})}if(we(Ce)){if(!De.accessRequests)return Ke(404,"AccessRequests endpoint is not configured");if(!await Mt(Ve))return Ke(401,"Authorization required");if(Ve.method==="GET"){if(!De.accessRequests.get)return Ke(404,"AccessRequests read endpoint is not configured");let Ue=Be.startsWith(`${Ce}/`)?Be.slice(Ce.length+1):void 0;if(!Ue||Ue.includes("/"))return Ke(404,"AccessRequest not found");let je;try{je=decodeURIComponent(Ue)}catch{return Ke(400,"AccessRequest id is invalid","invalidValue")}let We=await De.accessRequests.get(je);if(!We)return Ke(404,"AccessRequest not found");return St(We,200,We.trackingUrl)}if(Ve.method!=="POST"||Be!==Ce)return Ke(405,"Method not allowed");let be;try{be=await Ve.json()}catch{return Ke(400,"Request body must be valid JSON","invalidSyntax")}if(typeof be.subject!=="string"||!be.subject||typeof be.target!=="string"||!be.target||be.subjectType!=="user"&&be.subjectType!=="workload"&&be.subjectType!=="customer"||be.targetType!=="group"&&be.targetType!=="role"&&be.targetType!=="permission"||be.operation!=="grant"&&be.operation!=="revoke")return Ke(400,"subject, subjectType, targetType, target, and operation are required","invalidValue");let Re=await De.accessRequests.create({subject:be.subject,subjectType:be.subjectType,targetType:be.targetType,target:be.target,operation:be.operation,justification:typeof be.justification==="string"?be.justification:void 0});return St(Re.request,Re.created?201:200,Re.request.trackingUrl)}return Ke(404,"Resource not found")}let Ot;return Ot={...De,describe:()=>({module:"iam",active:!0,ready:Ot.isReady?.()??!0,url:De.url,deltaAudience:De.deltaAudience,accessRequests:{...De.url?{iam:`${R(De.url)}/AccessRequests`}:{},ciam:{}},users:{...fn(De.users),storeWired:De.userStore!==void 0},workloads:{...fn(De.workloads),storeWired:De.workloadIdentityStore!==void 0},customers:{...fn(De.customers),storeWired:De.customerStore!==void 0},groups:{enabled:pt,catalogWired:he!==void 0},urls:{usersUrl:De.usersUrl??"",groupsUrl:De.groupsUrl??"",workloadsUrl:De.workloadsUrl??"",customersUrl:De.customersUrl??""}}),users:fn(De.users),workloads:fn(De.workloads),customers:fn(De.customers),groups:{enabled:pt},createUser:ln,getBaseUrl:Sn,groups_outbound:xt,groups_inbound:Yt,users_inbound:Pt,workloads_inbound:At,customers_inbound:$t,handler:rn,delta:Ye},Ot}function Wr(T,_){let j=new TextEncoder().encode(T),X=typeof _==="string"?new TextEncoder().encode(_):_,le=new Uint8Array(j.length+1+X.length);return le.set(j,0),le[j.length]=46,le.set(X,j.length+1),le}function xo(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.length%4===0?"":"=".repeat(4-_.length%4),X=atob(_+j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function Po(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function As(T){let _=JSON.parse(T);if(!_||typeof _!=="object"||!Array.isArray(_.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return _}function Uo(T){return JSON.stringify(T)}async function Eo(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x},{name:"Ed25519"},!0,["verify"])}async function Do(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x,d:T.d},{name:"Ed25519"},!0,["sign"])}async function Mo(T){let j=(typeof T.jwks==="string"?As(T.jwks):T.jwks).keys.find((X)=>X.kid===T.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!j?.x)return!1;try{let X=await Eo(j),le=Wr(T.requestId,T.rawBody),ge=xo(T.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,ge,le)}catch{return!1}}async function Oo(T){let _=await Do(T.privateKeyJwk),j=Wr(T.requestId,T.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},_,j);return Po(new Uint8Array(X))}async function _o(T){let _=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),j=await crypto.subtle.exportKey("jwk",_.privateKey),le=(await crypto.subtle.exportKey("jwk",_.publicKey)).x,ge=j.d;if(!le||!ge)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:le,d:ge,kid:T,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:le,kid:T,alg:"EdDSA",use:"sig"}]}}}var _n={jwksTtlSeconds:{min:60,max:86400,default:600},jwksMaxEntries:{min:16,max:4096,default:256},sessionReadTtlSeconds:{min:1,max:300,default:30},sessionReadMaxEntries:{min:16,max:65536,default:1024}};function Fn(T,_){if(typeof T!=="number"||!Number.isFinite(T))return _.default;let j=Math.floor(T);if(j<_.min)return _.min;if(j>_.max)return _.max;return j}function Is(T){return{ttlMs:Fn(T?.ttlSeconds,_n.jwksTtlSeconds)*1000,maxEntries:Fn(T?.maxEntries,_n.jwksMaxEntries)}}function Ts(T){let _=T?.read;return{read:{enabled:_?.enabled===!0,ttlMs:Fn(_?.ttlSeconds,_n.sessionReadTtlSeconds)*1000,maxEntries:Fn(_?.maxEntries,_n.sessionReadMaxEntries)}}}function jo(T){return{jwks:Is(T?.jwks),session:Ts(T?.session)}}var Yn=new TextEncoder,Lo=new TextDecoder;function Us(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function xs(T){return Us(Yn.encode(JSON.stringify(T)))}function Es(T){if(!/^[A-Za-z0-9_-]+$/.test(T))return;let _=T.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(T.length/4)*4,"=");try{return Uint8Array.from(atob(_),(j)=>j.charCodeAt(0))}catch{return}}function Ps(T){let _=Es(T);if(!_)return;try{let j=JSON.parse(Lo.decode(_));return j!==null&&typeof j==="object"&&!Array.isArray(j)?j:void 0}catch{return}}function No(T){return Yn.encode(T)}function Ds(T){let _=new Uint8Array(T.byteLength);return _.set(T),_.buffer}async function Ms(T){return crypto.subtle.importKey("raw",Ds(No(T)),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function $o(T){let _=T.active.trim(),j=new Map(Object.entries(T.keys).map(([le,ge])=>[le.trim(),{kid:le.trim(),secret:ge}])),X=j.get(_);if(!_||!X?.secret)throw Error("Signing key ring must name a non-empty active key.");for(let le of j.values())if(!le.kid||!le.secret)throw Error("Signing key ring ids and secrets must be non-empty.");return{current:()=>X,find:(le)=>j.get(le)}}async function Wo(T,_,j){let X=Math.floor(j.ttlSeconds);if(!Number.isFinite(X)||X<1)throw Error("Compact JWT ttlSeconds must be a positive integer.");let le=_.current();if(!le.kid||!le.secret)throw Error("Signing key ring returned an invalid active key.");let ge=Math.floor(Date.now()/1000),he=xs({alg:"HS256",kid:le.kid,typ:"JWT"}),ke=xs({...T,iat:ge,exp:ge+X}),ye=`${he}.${ke}`,fe=await crypto.subtle.sign("HMAC",await Ms(le.secret),Yn.encode(ye));return`${ye}.${Us(new Uint8Array(fe))}`}async function Vo(T,_){let j=T.split(".");if(j.length!==3)return null;let[X,le,ge]=j;if(!X||!le||!ge)return null;let he=Ps(X);if(he?.alg!=="HS256"||he.typ!=="JWT"||typeof he.kid!=="string")return null;let ke=_.find(he.kid);if(!ke?.secret)return null;let ye=Es(ge);if(!ye)return null;if(!await crypto.subtle.verify("HMAC",await Ms(ke.secret),Ds(ye),Yn.encode(`${X}.${le}`)))return null;let ze=Ps(le);if(!ze)return null;let{iat:Ye,exp:Qe}=ze;if(typeof Ye!=="number"||typeof Qe!=="number"||!Number.isSafeInteger(Ye)||!Number.isSafeInteger(Qe))return null;let ct=Math.floor(Date.now()/1000);if(Ye>ct+60||Qe+60<=ct)return null;return ze}function qo(T){let _={};if(!T)return _;let j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;_[le.slice(0,ge).trim()]=le.slice(ge+1).trim()}return _}function Os(T){if(!T.expiresAt)return!1;let _=T.expiresAt instanceof Date?T.expiresAt:new Date(T.expiresAt);return!Number.isNaN(_.getTime())&&Date.now()>_.getTime()}function zo(T){if(!T||typeof T!=="object"||Array.isArray(T))return;let{access_token:_,id_token:j,refresh_token:X,tokens:le,...ge}=T;return ge}function jt(T,_){let j=T[_];return typeof j==="string"?j:""}function Bo(T,_){let j=T.exp;if(typeof j==="number")return new Date(j*1000);if(typeof j==="string"&&j.trim()){let X=Number(j);if(!Number.isNaN(X))return new Date(X*1000)}if(_ instanceof Date)return _;if(_){let X=new Date(_);if(!Number.isNaN(X.getTime()))return X}return new Date}function Go(T){let _=T.claims;if(!_?.sub||typeof _.sub!=="string")return;let j=Bo(_,T.expiresAt);if(T.authType==="sso")return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,sso:{profile:_,tenant:{id:jt(_,"idp")||jt(_,"iss"),name:jt(_,"iss")},tokenType:"Bearer",expires:j}};return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,userType:"customer",ciam:{profile:_,scope:"openid profile email",tokenType:"Bearer",expires:j}}}function Ko(T){if(T.authType!=="sso"&&T.authType!=="ciam")return;if(Os(T))return;return{sid:T.sid,authType:T.authType,tenantId:typeof T.tenantId==="string"?T.tenantId:void 0,sub:T.sub,expiresAt:T.expiresAt,createdAt:T.createdAt,claims:zo(T.claims)}}function Jo(T,_){if(!T.endsWith(".session"))return!1;if(!_||_.length===0)return!0;return _.some((j)=>T===`${j}.session`)}function Ho(T){if(T===void 0)return;let _=(Array.isArray(T)?T:[T]).map((j)=>j.trim()).filter((j)=>j.length>0);return _.length>0?_:void 0}async function _s(T,_,j){return(await js(T,_,j)).map(Ko).filter((le)=>Boolean(le))}async function js(T,_,j){let X=qo(T.headers.get("cookie")),le=Ho(j?.cookiesPrefix),ge=[],he=new Set;for(let[ke,ye]of Object.entries(X)){if(!Jo(ke,le)||!ye)continue;if(he.has(ye))continue;he.add(ye);let fe=await _.get(ye);if(!fe)continue;if(fe.authType!=="sso"&&fe.authType!=="ciam")continue;if(Os(fe))continue;ge.push(fe)}return ge}async function Fo(T,_,j){return(await _s(T,_,j)).map(Go).filter((le)=>Boolean(le))}var Yo="@ionite/core",Xo=l(y(Yo));async function Zo(T,_){let j=await Zt({idToken:T,jwksUri:_.jwksUri,issuer:_.issuer,audience:_.audience}),X=await Xo.validate(j);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((he)=>he.message).join("; ")}`);let le=X.value;if(le===void 0)throw Error("ID token claims missing");return H(le)}function wt(T){return Date.now()-T}function Vr(T){if(T instanceof Error)return{"error.name":T.name,"error.message":T.message};return{"error.name":typeof T,"error.message":String(T)}}function Xn(T,_){if(!T)return{};try{let j=new URL(T);return{[`${_}.origin`]:j.origin,[`${_}.path`]:j.pathname}}catch{return{[`${_}.path`]:T.startsWith("/")?T:`/${T}`}}}function Zn(T,_=5){if(!Array.isArray(T))return[String(T)];return T.slice(0,_).map((j)=>{if(!j||typeof j!=="object")return String(j);let X=j,le=Array.isArray(X.path)?X.path.join("."):String(X.path??""),ge=typeof X.message==="string"?X.message:String(X.message??"validation failed");return le?`${le}: ${ge}`:ge})}function Qo(T){if(!T||typeof T!=="object")return{};let _=T;return{oidc_error:typeof _.error==="string"?_.error:void 0,oidc_error_description:typeof _.error_description==="string"?_.error_description:void 0,oidc_error_uri:typeof _.error_uri==="string"?_.error_uri:void 0}}function ea(T,_={}){let j=typeof T==="string"?T:T?.headers.get("cookie")??void 0;if(!j)return[];let le=`${_.cookiePrefix??"ion.sso"}.`,ge=new Set;for(let he of Object.keys(na(j))){if(!he.startsWith(le))continue;let ke=he.slice(le.length),ye=ke.lastIndexOf(".");if(ye<=0)continue;let fe=ke.slice(0,ye).trim();if(fe)ge.add(fe)}return Array.from(ge)}function ta(T,_,j,X,le){if(!j&&!X)return;let ge=new WeakMap,he=new Map,ke={...j,...X},ye=!!(ke.authority&&ke.tokenUrl&&ke.authorizationUrl&&ke.clientId&&ke.redirectUri&&ke.scope),fe={...ke,authority:ye?t(ke.authority,"Missing 'authority' from SSO Config"):ke.authority,tokenUrl:ye?t(ke.tokenUrl,"Missing 'tokenUrl' from SSO Config"):ke.tokenUrl,authorizationUrl:ye?t(ke.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):ke.authorizationUrl,clientId:ye?t(ke.clientId,"Missing 'clientId' from SSO Config"):ke.clientId,redirectUri:ye?t(ke.redirectUri,"Missing 'redirectUri' from SSO Config"):ke.redirectUri,scope:ye?t(ke.scope,"Missing 'scope' from SSO Config"):ke.scope,responseType:ke.responseType??"code",cookiesSecure:ke.cookiesSecure!==void 0?ke.cookiesSecure:!0,cookiesSameSite:ke.cookiesSameSite!==void 0?ke.cookiesSameSite:"Strict",cookiesPrefix:ke.cookiesPrefix??(ke.clientId?`ion.sso.${ke.clientId}`:"ion.sso"),cookiesPath:ke.cookiesPath??"/",cookiesDomain:Nn(ke.cookiesDomain)},ze=Math.min(600,Math.max(0,Math.floor(Number(fe.rotationGraceSeconds??60))||0))*1000,Ye=Math.floor(Number(fe.sessionWindowSeconds??86400)),Qe=Number.isFinite(Ye)&&Ye>=1?Ye:86400;function ct(){let Ce=[];if(!fe.authority)Ce.push("authority");if(!fe.tokenUrl)Ce.push("tokenUrl");if(!fe.authorizationUrl)Ce.push("authorizationUrl");if(!fe.clientId)Ce.push("clientId");if(!fe.redirectUri)Ce.push("redirectUri");if(!fe.scope)Ce.push("scope");if(Ce.length>0)throw Error(`Missing OIDC configuration fields: ${Ce.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing ionite.`)}async function st(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me=ge.get(Ce);if(me)return me;let we=_e(Ce);return ge.set(Ce,we),we}async function _e(Ce){try{let{tokens:me,session:we,refreshedUser:be}=await At(Ce);if(!me)return{status:"unauthenticated"};if(we)vn(Ce,"user",we.entitlements);if(be)return{status:"authenticated",value:be};if(we?.claims)return{status:"authenticated",value:Rt(we.claims,me,xt(we.expiresAt))};return{status:"unauthenticated"}}catch(me){if(Ls(me))return{status:"unauthenticated"};return _.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},me),{status:"degraded",error:me instanceof Error?me:void 0}}}async function Le(Ce){let me=await st(Ce);return me.status==="authenticated"?me.value:void 0}async function et(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");ct();let me=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),we=t(fe.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),be=t(fe.clientId,"Missing 'clientId' from SSO Config"),Re=t(fe.scope,"Missing 'scope' from SSO Config"),Ue=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,je=_t(),We=_t(64),qe=_t(),Ee=me;try{new URL(Ee)}catch{if(Ue)try{let Te=new URL(Ue),xe=Ee.startsWith("//")?Ee.slice(1):Ee.startsWith("/")?Ee:`/${Ee}`;Ee=new URL(xe,Te.origin).toString()}catch{try{let Te=new URL(we),xe=Ee.startsWith("//")?Ee.slice(1):Ee.startsWith("/")?Ee:`/${Ee}`;Ee=new URL(xe,Te.origin).toString()}catch{throw Error(`Invalid redirectUri: "${me}". It must be a valid absolute URL.`)}}}let Ae=new URL(we);Ae.searchParams.append("client_id",be),Ae.searchParams.append("redirect_uri",Ee),Ae.searchParams.append("response_type","code"),Ae.searchParams.append("scope",Re),Ae.searchParams.append("state",je),Ae.searchParams.append("nonce",qe);let Se=await Pn(We);Ae.searchParams.append("code_challenge",Se),Ae.searchParams.append("code_challenge_method","S256");let ve=await fe.beforeLogin?.({request:Ce}),Ie=ve===void 0?{state:je,codeVerifier:We,nonce:qe}:{state:je,codeVerifier:We,nonce:qe,context:ve};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:Ae.toString(),"Set-Cookie":Wt(Je(je),Ie,fe.loginStateTtl??600,"Lax")}})}async function De(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me;try{me=await Le(Ce)}catch{me=void 0}let we=await fe.beforeLogout?.({request:Ce,user:me}),be=Ze("session",Ce),Re;try{Re=await At(Ce);let Se=Re.tokens?.refresh_token??Ze("refresh",Ce);if(Se)await Jt(Se)}catch(Se){_.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Se)}if(fe.sessionStore)try{let Se=Re?.sid??be;if(Se)await fe.sessionStore.delete(Se)}catch(Se){_.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Se)}let Ue=Ve(),je=await fe.afterLogout?.({request:Ce,context:we}),We=Qt(je,"/",Ce.url);if(We.response){let Se=new Headers(We.response.headers);for(let[,ve]of Ue)Se.append("Set-Cookie",ve);return new Response(We.response.body,{status:We.response.status,statusText:We.response.statusText,headers:Se})}let qe=We.location??"/",Ee=Ce.headers.get("accept");if(Ee?.includes(s)||Ee?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:qe}),{status:200,headers:[["Content-Type",s],...Ue]});return new Response("Logged out",{status:302,headers:[["Location",qe],...Ue]})}async function it(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");if(!fe.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!Ce.headers.get("content-type")?.includes(D))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let we=await Ce.text(),Re=new URLSearchParams(we).get("logout_token");if(!Re)return new Response("Missing logout_token parameter",{status:400});let Ue=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),je=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),We=fe.jwksUri||`${Ue}/protocol/openid-connect/certs`,qe=await Cr({logoutToken:Re,jwksUri:We,issuer:Ue,audience:je,log:_}),Ee=typeof qe.sid==="string"?qe.sid:void 0;if(!Ee)return _.warn("Back-Channel Logout: logout_token missing sid claim",{"ion.operation":"backchannel_logout","ion.outcome":"failure"}),new Response("Invalid logout_token: missing sid claim",{status:400});return await fe.sessionStore.delete(Ee),_.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:Ee}),new Response("OK",{status:200})}catch(me){return _.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},me),new Response("Internal Server Error",{status:500})}}async function pt(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me=Date.now(),we=new URL(Ce.url),be=new URLSearchParams(we.search);_.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":Ce.method,"url.path":we.pathname,hasCode:be.has("code"),hasState:be.has("state"),hasError:be.has("error"),...Xn(be.get("iss")??void 0,"oidc.issuer")});let Re=Object.fromEntries(be.entries()),Ue=await T.callbackParams.validate(Re);if(Ue.issues)return _.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":Zn(Ue.issues)}),ce(Ue.issues,"OIDC callback parameters validation failed");let{code:je,state:We}=Ue.value,qe;try{let Ee=t(We,'OIDC "state" was not present in the callback parameters'),Ae=Ze(Je(Ee),Ce,!0),{codeVerifier:Se,state:ve,nonce:Ie,context:Te}=Ae??{};qe=Te,_.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(Ae),hasCodeVerifier:Boolean(Se),hasStateVerifier:Boolean(ve),hasNonce:Boolean(Ie),hasContext:Te!==void 0});let xe=t(Se,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');t(ve,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let Ne=t(Ie,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),Oe=t(je,'OIDC "code" was not present in the callback parameters');if(We!==ve)throw _.warn("SSO callback state verification failed",{"ion.event":"ion.sso.callback.state_verification_failed","ion.operation":"sign_in.callback","ion.outcome":"failure"}),Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');_.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let Ge=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,Fe=await Mt(Oe,xe,Ge),{tokenExpiresAt:rt,sessionExpiresAt:at}=bt(Fe);Fe.expires=rt.toISOString();let ft=Date.now();_.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let dt=await mt(Fe,Ne,at);_.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(ft),"user.id":dt.id});let nt,ht;{let Ct=Ht("SSO requires sessionStore configuration for opaque session cookies."),Vt=typeof dt.sso.profile.sid==="string"?dt.sso.profile.sid:void 0,Dt=Vt||_t(32),vt=dt.id;if(_.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(Dt),hasIdpSid:Boolean(Vt),hasSub:Boolean(vt),"user.id":vt}),!vt)throw Error("Session creation failed: missing sub in ID token claims");let qt=Date.now(),wn=await nn({sid:Dt,sub:vt,idpSid:Vt,authType:"sso",tenantId:fe.tenantId,tokens:Fe,claims:dt.sso.profile,expiresAt:at,createdAt:new Date},vt,dt.sso.profile,Fe);await dn(Ct,wn),ht=wn,nt=["Set-Cookie",Wt("session",Dt,at)],_.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":wt(qt),"user.id":vt})}if(fe.userStore)try{let Ct=dt.id;if(Ct){let Vt=new Date,Dt=Date.now();_.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":Ct});let vt=await fe.userStore.get(Ct);if(_.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":wt(Dt),"user.id":Ct,found:Boolean(vt)}),vt||fe.enableJitUserProvisioning){let qt=Date.now(),wn={...vt??{},...dt,id:Ct,tenantId:vt?.tenantId,createdAt:vt?.createdAt??Vt,updatedAt:Vt};await fe.userStore.upsert(wn),_.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":wt(qt),"user.id":Ct,existing:Boolean(vt),jitProvisioning:Boolean(fe.enableJitUserProvisioning)})}else _.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":Ct})}else _.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(Ct){_.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...Vr(Ct)})}_.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":wt(me),"user.id":dt.id});let tt=[["Set-Cookie",rn(Je(Ee))],...nt?[nt]:[],...nt?await Be(Ce,await Tt(dt),at):[]],Ut=await fe.afterLogin?.({ok:!0,request:Ce,user:dt,session:ht,context:qe,displayCookie:fe.displayCookie,displayCookieAttributes:Ot()}),Et=Qt(Ut,"/",Ce.url);if(Et.response)return sn(Et.response,tt.map(([,Ct])=>Ct));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",Et.location],...tt]})}catch(Ee){_.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":wt(me),...Vr(Ee)});let Ae=We?[["Set-Cookie",rn(Je(We))]]:[],Se=await fe.afterLogin?.({ok:!1,request:Ce,error:Ee,context:qe,displayCookie:fe.displayCookie,displayCookieAttributes:Ot()}),ve=Qt(Se,"/",Ce.url);if(ve.response)return sn(ve.response,Ae.map(([,Ie])=>Ie));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",ve.location],...Ae]})}}function bt(Ce){let me=Date.now(),we=Number(Ce.expires_in??3600)||3600,be=new Date(me+we*1000),Re;if(Ce.refresh_expires_in!=null&&Number.isFinite(Number(Ce.refresh_expires_in)))Re=Number(Ce.refresh_expires_in);else if(Ce.refresh_token)Re=Qe;else Re=we;return{tokenExpiresAt:be,sessionExpiresAt:new Date(me+Re*1000)}}async function mt(Ce,me,we){if(!fe)throw Error("ionite SSO Manager not initialized");let be=Date.now(),Re=await un(Ce.id_token,me);return _.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(be),"user.id":Re.sub,hasEmail:Boolean(Re.email),hasName:Boolean(Re.name)}),Rt(Re,Ce,we)}function Rt(Ce,me,we){let be=we??bt(me).sessionExpiresAt,Re=Ce.ecid!==void 0&&Ce.ecid!==null?O(Ce.ecid):void 0;return{id:Ce.sub,userName:Ce.preferred_username||"",name:Ce.name||"",email:Ce.email||"",emails:[{value:Ce.email||"",primary:!0}],...Re?{ecid:Re}:{},avatar:Ce.picture,sso:{profile:{...Ce},tenant:{id:Ce.idp||Ce.iss||"",name:Ce.iss||""},scope:me.scope,tokenType:me.token_type,sessionState:me.session_state,expires:be}}}async function Tt(Ce){if(!fe.userStore)return Ce;let me=await fe.userStore.lookup(Ce);if(!me)return Ce;return{...Ce,...me,id:Ce.id,sso:Ce.sso}}async function Mt(Ce,me,we){if(!fe)throw Error("ionite SSO Manager not initialized");ct();let be=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),Re=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),Ue=t(fe.clientId,"Missing 'clientId' from SSO Config"),je=Re;try{new URL(je)}catch{if(we)try{let qe=new URL(we),Ee=je.startsWith("//")?je.slice(1):je.startsWith("/")?je:`/${je}`;je=new URL(Ee,qe.origin).toString()}catch{try{let qe=new URL(be),Ee=je.startsWith("//")?je.slice(1):je.startsWith("/")?je:`/${je}`;je=new URL(Ee,qe.origin).toString()}catch{throw Error(`Invalid redirectUri: "${Re}". It must be a valid absolute URL.`)}}}let We=new URLSearchParams;if(We.append("grant_type","authorization_code"),We.append("code",Ce),We.append("redirect_uri",je),We.append("client_id",Ue),fe.clientSecret)We.append("client_secret",fe.clientSecret);We.append("code_verifier",me);try{let qe=Date.now();_.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...Xn(be,"oidc.token_url"),...Xn(je,"oidc.redirect_uri"),hasClientSecret:Boolean(fe.clientSecret)});let Ee=await fetch(be,{method:"POST",headers:{...h,...i},body:We.toString()});_.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":Ee.status,"duration.ms":wt(qe)}),_.debug("SSO token exchange response body read started",{"ion.event":"ion.sso.token.response_body_read_started","ion.module":"sso","ion.operation":"token.exchange"});let Ae=await a(Ee,{log:_,operation:"token.exchange"});if(_.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":wt(qe)}),!Ee.ok){_.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":Ee.status,"duration.ms":wt(qe),...Qo(Ae)});let ve=Ae;throw Error(`Token exchange failed: ${ve.error||Ee.statusText} - ${ve.error_description||""}`.trim())}let Se=await T.tokenResponse.validate(Ae);if(Se.issues)throw _.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":wt(qe),"validation.issues":Zn(Se.issues)}),Error(`Token response validation failed: ${Se.issues}`);return _.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":wt(qe),tokenType:Se.value.token_type,hasAccessToken:Boolean(Se.value.access_token),hasIdToken:Boolean(Se.value.id_token),hasRefreshToken:Boolean(Se.value.refresh_token),expiresIn:Se.value.expires_in}),Se.value}catch(qe){throw _.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...Vr(qe)}),qe}}async function kn(Ce){return yr(async()=>{if(!fe)throw Error("ionite SSO Manager not initialized");ct();let me=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),we=t(fe.clientId,"Missing 'clientId' from SSO Config"),be=new URLSearchParams;if(be.append("grant_type","refresh_token"),be.append("refresh_token",Ce),be.append("client_id",we),fe.clientSecret)be.append("client_secret",fe.clientSecret);let Re=await fetch(me,{method:"POST",headers:{...h,...i},body:be.toString()}),Ue=await a(Re,{log:_,operation:"token.refresh"});if(!Re.ok){_.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:Ue});let We=Ue;throw Error(`Token refresh failed: ${We.error||Re.statusText} - ${We.error_description||""}`.trim())}let je=await T.tokenResponse.validate(Ue);if(je.issues)throw _.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":Zn(je.issues)}),Error(`Token refresh response validation failed: ${je.issues}`);return je.value},void 0,void 0,void 0,_)}async function Jt(Ce){try{if(!fe)throw Error("ionite SSO Manager not initialized");if(!fe.revocationEndpoint)return;let me=t(fe.clientId,"Missing 'clientId' from SSO Config"),we=new URLSearchParams;if(we.append("token",Ce),we.append("token_type_hint","refresh_token"),we.append("client_id",me),fe.clientSecret)we.append("client_secret",fe.clientSecret);let be=await fetch(fe.revocationEndpoint,{method:"POST",headers:{...i,...h},body:we.toString()});if(!be.ok)_.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:be.status,statusText:be.statusText});else _.info("Token revoked successfully",{"ion.module":"sso"})}catch(me){_.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},me)}}async function Sn(){if(!fe)throw Error("ionite SSO Manager not initialized");let Ce=fe.authority;if(!fe.jwksUri&&!Ce)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let me=fe.jwksUri||`${Ce}/protocol/openid-connect/certs`;return In(me,_)}async function un(Ce,me){let we=Date.now(),be=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),Re=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),Ue=fe.jwksUri||`${be}/protocol/openid-connect/certs`;_.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...Xn(Ue,"oidc.jwks_uri")});let je;try{je=await Zt({idToken:Ce,jwksUri:Ue,issuer:be,audience:Re,expectedNonce:me,log:_})}catch(qe){throw _.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":wt(we)},qe),qe}_.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":wt(we)});let We=await T.idTokenClaims.validate(je);if(We.issues)throw _.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":wt(we),"validation.issues":Zn(We.issues)}),Error(`ID token claims validation failed: ${We.issues}`);return _.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":wt(we),"user.id":We.value.sub,hasIssuer:Boolean(We.value.iss),hasAudience:Boolean(We.value.aud)}),We.value}function Ht(Ce="SSO sessionStore is required for opaque session cookies."){if(!fe.sessionStore)throw Error(Ce);return fe.sessionStore}let Ft=!1;async function nn(Ce,me,we,be){let Re=fe.claimsAsEntitlements;if(!Re?.claims?.length)return Ce;if(fe.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Ft)Ft=!0,_.warn("SSO claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.sso.claims.incapable","ion.module":"sso","ion.outcome":"degraded"});return Ce}let Ue=await bn({block:Re,claims:we,accessClaims:Cn(be?.access_token),scope:be?.scope,subjectType:"user",subjectId:me,catalog:le?.catalogView?.(),log:_});return{...Ce,entitlements:Ue}}async function dn(Ce,me){try{await Ce.create(me)}catch(we){if(!await Ce.get(me.sid))throw we;await Ce.update(me.sid,me)}}function xt(Ce){if(!Ce)return;if(Ce instanceof Date)return Ce;let me=new Date(Ce);return Number.isNaN(me.getTime())?void 0:me}function ln(Ce){let me=Ce.tokens;if(!me?.access_token||!me.id_token||!me.token_type)return;return me}async function Yt(Ce,me=!1){let we=Ht(),be=Ze("session",Ce);if(!be)return{tokens:void 0,refreshHeaders:[]};let Re=await we.get(be);if(Re&&fe.tenantId&&Re.tenantId&&Re.tenantId!==fe.tenantId)return{tokens:void 0,refreshHeaders:Ve(),sid:be};if(Re?.authType!=="sso")return{tokens:void 0,refreshHeaders:Ve(),sid:be};let Ue=ln(Re);if(!Ue)return{tokens:void 0,refreshHeaders:Ve(),sid:be};let je=xt(Re.expiresAt);if(je?Date.now()>je.getTime():!1)return await we.delete(be),{tokens:void 0,sid:be,refreshHeaders:Ve()};let qe=xt(Ue.expires),Ee=qe?Date.now()>qe.getTime():!0;if((me||Ee)&&Ue.refresh_token)return Pt(Ce,be,Re,Ue);return{tokens:Ue,sid:be,session:Re,refreshHeaders:Xe(Ce)}}function Pt(Ce,me,we,be){let Re=he.get(me);if(Re)return Re;let Ue=Ht(),je=(async()=>{let We=await kn(be.refresh_token),{tokenExpiresAt:qe,sessionExpiresAt:Ee}=bt(We);We.expires=qe.toISOString();let Ae=await mt(We,void 0,Ee),Se=Ae.sso.profile,ve=_t(32),Ie=await nn({...we,sid:ve,tokens:We,claims:Se,expiresAt:Ee,createdAt:new Date},we.sub,Se,We);await dn(Ue,Ie);try{if(ze<=0)await Ue.delete(me);else{let{refresh_token:Te,...xe}=be;await Ue.update(me,{tokens:xe,expiresAt:new Date(Date.now()+ze)})}}catch(Te){_.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},Te)}return{tokens:We,sid:ve,session:Ie,refreshedUser:Ae,refreshHeaders:[["Set-Cookie",Wt("session",ve,Ee)],...await Be(Ce,Ae,Ee)]}})();return he.set(me,je),je.finally(()=>{he.delete(me)})}async function At(Ce,me=!1){return Yt(Ce,me)}async function $t(Ce){let{tokens:me}=await At(Ce);if(!me)return;return me.access_token}function Wt(Ce,me,we,be=fe.cookiesSameSite??"Strict"){if(!fe)throw Error("ionite SSO Manager not initialized");if(Ce=`${fe.cookiesPrefix}.${Ce}`,typeof me!=="string")me=btoa(JSON.stringify(me));let Re;if(we instanceof Date)Re=`Expires=${we.toUTCString()}`;else if(typeof we==="number")Re=`Max-Age=${we}`;else throw Error("Invalid expires type",we);if(me.length>4000)throw Error(`Error setting cookie: ${Ce}. Cookie length is: ${me.length}`);return`${Ce}=${me}; ${Re}; Path=${fe.cookiesPath};${Xt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${be};`}function rn(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");return`${fe.cookiesPrefix}.${Ce}=; Max-Age=0; Path=${fe.cookiesPath};${Xt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${fe.cookiesSameSite};`}function Ot(){return{path:fe.cookiesPath??"/",domain:fe.cookiesDomain,secure:fe.cookiesSecure!==!1,sameSite:fe.cookiesSameSite??"Strict"}}function Ve(){return[["Set-Cookie",rn("session")],["Set-Cookie",Bt(`${fe.cookiesPrefix}.profile`,Ot())]]}function Xe(Ce){if(fe.displayCookie?.enabled===!0)return[];return mn(Ce.headers.get("cookie"),fe.cookiesPrefix??"ion.sso",Ot()).map((me)=>["Set-Cookie",me])}async function Be(Ce,me,we){return(await Rn({cookieHeader:Ce.headers.get("cookie"),sessionStore:fe.sessionStore,cookiesPrefix:fe.cookiesPrefix??"ion.sso",authType:"sso",tenantId:fe.tenantId,expiresAt:we,user:me,projector:fe.displayUser,displayCookie:fe.displayCookie,trim:fe.trimDisplayCookies,attr:Ot()})).map((Re)=>["Set-Cookie",Re])}function Ze(Ce,me,we=!1){if(!fe)throw Error("ionite SSO Manager not initialized");let be=me.headers.get("cookie");if(!be)return null;let Re=`${fe.cookiesPrefix}.${Ce}`,Ue=be.split(";").find((Ee)=>Ee.trim().startsWith(`${Re}=`));if(!Ue)return null;let je=Ue.indexOf("="),We=Ue.slice(je+1).trim();if(!we)return We;let qe=atob(We);return JSON.parse(qe)}function Je(Ce){return`state_${Ce}`}async function He(Ce,me){if(!fe)throw Error("ionite SSO Manager not initialized");let{loginUrl:we,userUrl:be,tokenUrl:Re,refreshUrl:Ue,logoutUrl:je,logoutBackChannelUrl:We,jwksUrl:qe,redirectUri:Ee}={...fe,...me},Ae=new URL(Ce.url).pathname;if(Ee){let Se;try{Se=new URL(Ee).pathname}catch{try{let ve=new URL(Ce.url),Ie=Ee.startsWith("//")?Ee.slice(1):Ee;Se=new URL(Ie,ve.origin).pathname}catch{Se=Ee.startsWith("/")?Ee:`/${Ee}`}}if(Se===Ae)return pt(Ce)}if(we===Ae)return et(Ce);if(be===Ae){if((fe.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Xe(Ce)});try{let{tokens:Se,session:ve,refreshedUser:Ie,refreshHeaders:Te}=await At(Ce);if(!Se)return new Response("User not logged in",{status:401,headers:Te});let xe=Ie??(ve?.claims?Rt(ve.claims,Se,xt(ve.expiresAt)):void 0);if(!xe)return new Response("User not logged in",{status:401,headers:Te});let Ne=await Tt(xe),Oe=`${fe.cookiesPrefix}.profile`,Ge=xt(ve?.expiresAt),Fe=fe.displayCookie?.enabled===!0&&Ge&&!Ze("profile",Ce)&&!Te.some(([,at])=>at.startsWith(`${Oe}=`))?await Be(Ce,Ne,Ge):[],rt=fe.userEndpoint==="display"?m(Ne,fe.displayUser):Ne;return new Response(JSON.stringify(rt),{headers:[["Content-Type",s],...Te,...Fe]})}catch(Se){if(Ls(Se))return new Response("User not logged in",{status:401});return _.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},Se),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r})}}if(Re===Ae){let{tokens:Se,refreshHeaders:ve}=await At(Ce);if(!Se)return new Response("User not logged in",{status:401,headers:ve});return new Response(JSON.stringify({token:Se.access_token,expires:Se.expires}),{headers:[["Content-Type",s],...ve]})}if(Ue===Ae){let{tokens:Se,refreshHeaders:ve}=await At(Ce,!0);if(!Se)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:ve})}if(je===Ae)return De(Ce);if(We===Ae)return it(Ce);if(qe===Ae){let Se=await Sn();return new Response(JSON.stringify(Se),{headers:[["Content-Type",s]]})}return new Response("Not Found",{status:404})}let ut;return ut={...fe,describe:()=>({module:"sso",active:!0,ready:ut.isReady?.()??!0,authority:fe.authority,tokenUrl:fe.tokenUrl,authorizationUrl:fe.authorizationUrl,clientId:fe.clientId,redirectUri:fe.redirectUri,responseType:fe.responseType,scope:fe.scope,silentRedirectUri:fe.silentRedirectUri,jwksUri:fe.jwksUri,endSessionEndpoint:fe.endSessionEndpoint,revocationEndpoint:fe.revocationEndpoint,cookies:{prefix:fe.cookiesPrefix,path:fe.cookiesPath,secure:fe.cookiesSecure,sameSite:fe.cookiesSameSite,domain:fe.cookiesDomain},loginStateTtl:fe.loginStateTtl,rotationGraceSeconds:fe.rotationGraceSeconds,sessionWindowSeconds:fe.sessionWindowSeconds,displayCookie:fe.displayCookie,jit:{enabled:fe.enableJitUserProvisioning===!0,userStore:fe.userStore!==void 0},sessionStore:fe.sessionStore!==void 0,...fe.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...fe.claimsAsEntitlements.claims],expand:fe.claimsAsEntitlements.expand===!0,resources:fe.claimsAsEntitlements.expand===!0&&fe.claimsAsEntitlements.resources===!0,capable:fe.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},urls:{loginUrl:fe.loginUrl??"",userUrl:fe.userUrl??"",logoutUrl:fe.logoutUrl??"",logoutBackChannelUrl:fe.logoutBackChannelUrl??"",refreshUrl:fe.refreshUrl??"",callbackUrl:fe.redirectUri??""}}),getUser:Le,resolveUser:st,getJwt:$t,initiateLogin:et,logout:De,logoutBackChannel:it,callbackHandler:pt,handler:He},ut}function na(T){let _={},j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;let he=le.slice(0,ge).trim(),ke=le.slice(ge+1).trim();_[he]=ke}return _}function Ls(T){if(!(T instanceof Error))return!1;return["Public key not found","Invalid JWT","Invalid JWT signature","ID token expired","ID token issuer mismatch","ID token audience mismatch","ID token nonce mismatch","ID token missing exp","invalid_grant"].some((_)=>T.message.includes(_))}function Ns(T){return T=T??"SSO Unavailable",new Response(JSON.stringify({error:T}),{status:503,statusText:T,headers:r})}var Qn="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function ra(T,_){return t(_,Qn),_.sso?.getUser(T)}async function qr(T,_){return t(_,Qn),await _.sso?.resolveUser(T)??{status:"unauthenticated"}}async function sa(T,_){t(_,Qn);let j=_.sso;if(!j)return Ns();return j.initiateLogin(T)}async function ia(T,_){t(_,Qn);let j=_.sso;if(!j)return Ns();return j.callbackHandler(T)}var Br="tenant.owner",zr="tenant.owner.",oa="tenant:";function aa(T){return{id:Br,name:"Tenant owner",description:"Administer one tenant resource",requestable:!1,permissionTypes:["Admin"],resourceTypes:["tenant"],assignableSubjectTypes:["customer"],...T}}function Gr(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${oa}${_}`}function ca(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${zr}${_}`}function gt(T){return{allow:!1,reason:T,response(){if(T==="not_found")return Response.json({error:"Not Found"},{status:404});if(T==="forbidden")return Response.json({error:"Forbidden"},{status:403});if(T==="unavailable")return Response.json({error:"Tenant runtime unavailable"},{status:503});return Response.json({error:"Unauthorized"},{status:401})}}}function er(T,_){if(!T.id)return gt("unavailable");return{allow:!0,session:{id:T.id,email:T.email,name:T.name,kind:_}}}function $s(T){return T==="access_index_not_configured"||T==="error"}async function Ws(T,_){let j;try{j=await Vn(T,_.rootIon)}catch{return gt("unavailable")}if(j.status==="degraded")return gt("unavailable");if(j.status==="unauthenticated")return gt("unauthenticated");if(!j.value.id)return gt("unavailable");try{let X=await _.rootIon.authz.hasPermission(j.value.id,_.ownerPermission??Br,Gr(_.tenantId),"customer");if(X.allow)return er(j.value,"owner");return gt($s(X.metadata?.reason)?"unavailable":"forbidden")}catch{return gt("unavailable")}}async function ua(T,_){let{tenantIon:j}=_;if(!j)return gt("not_found");if(j.isReady()){let le;try{le=await qr(T,j)}catch{return gt("unavailable")}if(le.status==="degraded")return gt("unavailable");if(le.status==="authenticated"){if(!le.value.id)return gt("unavailable");if(!_.permission)return er(le.value,"sso");try{let ge=await j.authz.hasPermission(le.value.id,_.permission,void 0,"user");if(ge.allow)return er(le.value,"sso");return gt($s(ge.metadata?.reason)?"unavailable":"forbidden")}catch{return gt("unavailable")}}if(_.allowTenantCustomer){let ge;try{ge=await Vn(T,j)}catch{return gt("unavailable")}if(ge.status==="degraded")return gt("unavailable");if(ge.status==="authenticated"){if(!ge.value.id)return gt("unavailable");return er(ge.value,"customer")}}}let X=await Ws(T,_);if(X.allow||X.reason==="unavailable")return X;if(!j.isReady())return gt("unavailable");return gt("unauthenticated")}async function da(T,_){let j=T.authz.accessStore;if(!j)throw Error("Cannot list owned tenants: no AccessAssignmentStore is wired.");let X=new Set;for await(let le of c((ge,he)=>j.listBySubject(_,"customer",{start:ge,limit:he}))){let ge=typeof le.target==="string"?le.target:le.target.id;if(le.targetType!=="group"||!ge.startsWith(zr))continue;let he=ge.slice(zr.length);if(!he||!le.resources?.includes(Gr(he)))continue;X.add(he)}return[...X].sort()}function la(T,_){let j=_.redirectTo.trim()||"/",X=_.tenantIon?.sso?.isReady?.()===!0?`${_.tenantIonBasePath?.(T)??`/api/${encodeURIComponent(T)}/ionite`}/auth/login`:_.fallbackPath,le=new URL(X,"http://localhost");return le.searchParams.set("redirect",j),`${le.pathname}${le.search}`}export{_n as CACHE_BOUNDS,Yr as CIAM_PROVIDER_PRESETS,Q as CatalogAdjacencyCache,Me as InMemoryTenantStore,Br as TENANT_OWNER_PERMISSION,Li as allowHosts,ji as allowOrigins,ms as allowRelativePaths,fs as allowSameOrigin,Rs as assertSubjectTypeAssignable,us as assertTrustedIdTokenClaims,Er as baseCustomerToScim,Pr as baseUserToScimUser,Ur as baseWorkloadToScim,ps as blockDangerousUrls,wr as buildAuthorizationUrl,Wr as buildLfvSigningInput,ia as callback,$i as captureRedirect,zi as ciam,Ei as clearDiscoveryCache,bi as clearJwksCache,$e as collectReferencedDefinitions,yi as configureJwksCache,Cn as decodeUnverifiedJwtPayload,Ni as defaultRedirectPolicies,bn as deriveClaimsEntitlements,nr as derivedEntitlementsFor,vr as discoverOidcEndpoints,js as discoverSessionRecords,_s as discoverSessions,xr as entitlementToScimGroup,br as exchangeAuthorizationCode,E as expandRoot,Rr as fetchUserInfo,Bt as formatDisplayClearCookie,dr as formatDisplaySetCookie,Ar as generateAppleClientSecret,_o as generateLfvEd25519KeyPair,hr as getCachedVerificationKey,Bi as getCustomer,Fo as getDiscoveredSessionUsers,In as getJwks,da as getOwnedTenantIds,ir as getProviderPreset,Ri as getPublicKeyForKid,vi as getPublicKeyFromJwks,ra as getUser,kr as getVerificationKeyForKid,ri as has,ci as hasAll,li as hasAllScope,ai as hasAny,di as hasAnyScope,oi as hasGroup,si as hasPermission,ii as hasRole,ui as hasScope,To as iam,sa as initiateLogin,gs as isRedirectAllowed,ea as listSsoClientIdsFromCookies,xn as normalizeOidcIssuer,ar as orderedEnabledProviders,As as parseLfvJwks,Pn as pkceChallengeFromVerifier,gi as planDiscoveredTenantCookies,mn as planDisplayCookieClear,Rn as planDisplayCookieHeaders,pe as reconcileSubjectAccess,vn as rememberDerivedEntitlements,Qt as resolveAfterRedirect,jo as resolveCacheConfig,Wi as resolveCapturedRedirect,Ln as resolveCiamProvider,Vn as resolveCustomer,Ci as resolveJwkForKid,Is as resolveJwksCacheConfig,or as resolveProviderBranding,Tr as resolveRedirect,Ts as resolveSessionCacheConfig,Ws as resolveTenantOwner,ua as resolveTenantSession,qr as resolveUser,Ir as sameOriginRedirectRules,Qr as selectDisplayCookies,ot as sendTenantWebhook,Ui as setDiscoveryClock,hi as setJwksClock,ki as setJwksRetry,Wo as signCompactJwt,Oo as signLfvPayload,ta as sso,$o as staticSigningKeyRing,Uo as stringifyLfvJwks,la as tenantAccessLoginUrl,ca as tenantOwnerEntitlementId,aa as tenantOwnerPermission,Gr as tenantResourceId,Vo as verifyCompactJwt,Zt as verifyIdToken,Mo as verifyLfvSignature,Cr as verifyLogoutToken,Zo as verifyUser,sn as withSetCookies};
1
+ import{J,d,A,I,v,o,c,Y,f,e,g,x,N,L,K,Z,q,n,p,Q,E,pe,$e,W,ee,te,V,ne,m,z,re,B,P,U,G,O,se,oe,ie,y,s,D,i,ae,r,w,h,F,a,l,t,ce,R,S,H,k,M,Me,ot,u,b,C,ue,de}from"./shared/core-knezf9yx.js";var Gs=new Set(se.map((T)=>T.id));async function vn(T){let _=Ks(T.block);if(_.length===0||!T.subjectId)return[];let j=Js(T.claims,T.accessClaims,T.scope),X=T.block.expand===!0,le=X&&T.block.resources===!0,ge=[],ye=new Set,Se=(he)=>{let me=`${he.targetType}:${he.target}:${he.resource??""}`;if(ye.has(me))return;ye.add(me),ge.push(he)};for(let he of _){let me=Hs(j,he);for(let ze of me){let Je=await Ys(T.catalog,ze);if(!Je){T.log?.debug("claims entitlement dropped: value is not a catalog id",{"ion.event":"ion.authz.claims.unmatched","ion.module":"authz",claim:he,value:ze});continue}if(!X||!T.catalog){Se({targetType:Je,target:ze,claim:he});continue}let Qe={subject:T.subjectId,subjectType:T.subjectType,targetType:Je,target:ze,...le?Qs(await Zs(T.catalog,Je,ze)):{applyToApplication:!0}},ut=await E(Qe,T.catalog),st=Qe.id;for(let Ne of ut){if(Ne.resource&&!le)continue;Se({targetType:Ne.targetType,target:Ne.target,...Ne.resource?{resource:Ne.resource}:{},claim:he,root:st??Ne.rootId})}}}return ge}function mn(T){if(!T)return;let _=T.split(".");if(_.length!==3||!_[1])return;try{let j=_[1].replace(/-/g,"+").replace(/_/g,"/"),X=j.padEnd(j.length+(4-j.length%4)%4,"="),le=JSON.parse(atob(X));return le&&typeof le==="object"&&!Array.isArray(le)?le:void 0}catch{return}}var rr=new WeakMap;function Rn(T,_,j){let X=rr.get(T)??{};X[_]=j??[],rr.set(T,X)}function sr(T,_){return rr.get(T)?.[_]}function Ks(T){return T.claims.filter((_)=>typeof _==="string"&&_.length>0)}function Js(T,_,j){let X={...T};if(_){for(let[le,ge]of Object.entries(_))if(X[le]===void 0)X[le]=ge}if(X.scope===void 0&&j)X.scope=j;return X}function Hs(T,_){let j=Fs(T,_);if(typeof j==="string")return _==="scope"||_.endsWith(".scope")?j.split(/\s+/).filter(Boolean):j.length>0?[j]:[];if(Array.isArray(j))return j.filter((X)=>typeof X==="string"&&X.length>0);return[]}function Fs(T,_){let j=T;for(let X of _.split(".")){if(!j||typeof j!=="object"||Array.isArray(j))return;j=j[X]}return j}async function Ys(T,_){if(Gs.has(_))return"permission";if(!T)return;for(let j of["permission","role","group"])if(await Xs(T,j,_))return j;return}async function Xs(T,_,j){if(Fr(T,_,j))return!0;let le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups;if(!le)return!1;return await le.get(j)!==void 0}function Fr(T,_,j){if(!T.code)return;if(_==="permission")return T.code.permissions.get(j);if(_==="role")return T.code.roles.get(j);return T.code.groups.get(j)}async function Zs(T,_,j){let X=Fr(T,_,j),le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups,Se=((le?await le.get(j):void 0)?.resources??X?.resources??[]).map((he)=>he.trim()).filter(Boolean);return Se.length>0?Se:void 0}function Qs(T){if(!T||T.length===0)return{applyToApplication:!0};return{resources:T}}var ei="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",Yr=["user","customer","workload"],ti={user:async(T,_)=>_.sso?.getUser(T),customer:async(T,_)=>_.ciam?.getCustomer(T),workload:async(T,_)=>{let j=await _.workload?.getWorkloadIdentity?.(T);if(!j)return;let X=j.clientId??j.workloadId??j.claims.sub;return X?{...j,id:X}:void 0}};function ni(T){if(T==="any")return Yr;let _=Array.isArray(T)?T:[T];return Yr.filter((j)=>_.includes(j))}function ri(T){let _=T.headers.get("cookie");if(!_)return[];return _.split(";").map((j)=>j.slice(0,j.indexOf("=")===-1?j.length:j.indexOf("=")).trim()).filter(Boolean)}function si(T,_){let j=T.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=ri(T),le=new Set;for(let ye of X){if(ye.startsWith("ion.sso"))le.add("user");if(ye.startsWith("ion.ciam"))le.add("customer")}let ge=X.length>0&&!le.has("user")&&!le.has("customer");return _.filter((ye)=>{if(ye==="workload")return j;if(X.length===0)return!1;return le.has(ye)||ge})}function lt(T){return typeof T==="string"?T:T.id}function ii(T){let{subject:_,subjectType:j}=T,X;if(j==="user")X=_.sso?.scope;else if(j==="customer")X=_.ciam?.scope;else if(j==="workload")X=_.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function or(T,_,j){let X=ii(T),le=_.filter((ye)=>X.has(ye));return{allow:j==="any"?le.length>0:_.length>0&&le.length===_.length,metadata:{reason:"scope",wantedScopes:_,matchedScopes:le}}}function Xr(T,_){if(T.targetType!==_.targetType||T.target!==_.id)return!1;return _.resource?T.resource===_.resource:T.resource===void 0}function fn(T,_){return(j)=>{if(T.length===0)return;let X=j.derivedEntitlements??[];if(X.length===0)return;let le=T.filter((ye)=>X.some((Se)=>Xr(Se,ye)));if(!(_==="any"?le.length>0:le.length===T.length))return;return X.filter((ye)=>le.some((Se)=>Xr(ye,Se)))}}function jn(T,_,j){return(X)=>{if(_.length===0||X.subjectType!=="workload")return;let le=J(T.config?.authz,X.subject);if(!le)return;let ge=_.filter((Se)=>le.has(Se));return(j==="any"?ge.length>0:ge.length===_.length)?ge:void 0}}function ir(T,_,j,X,le){return{allow:j==="ok",subject:_?.subject,subjectType:_?.subjectType,reason:j,decision:X,response(){if(j==="ok")return new Response(null,{status:204});if(j==="unauthenticated")return T.log.warn("authz.denied",{reason:j,...le()}),Response.json({error:"Unauthorized"},{status:401});if(j==="not_configured")return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"not_configured"},{status:503});return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"Forbidden"},{status:403})}}}function oi(T,_,j){return new Promise((X)=>{let le=[],ge=T.length,ye=!1,Se=()=>{if(ge-=1,ge===0&&!ye)ye=!0,X({outcomes:le})};for(let he of T)_(he).then((me)=>{if(le.push({principal:he,decision:me}),!ye&&me.allow){ye=!0,X({matched:{principal:he,decision:me},outcomes:le});return}Se()},(me)=>{j?.(he,me),le.push({principal:he,decision:{allow:!1,metadata:{reason:"error"}}}),Se()})})}async function zt(T,_,j,X,le,ge,ye){t(_,ei);let Se=si(T,ni(j)),me=(await Promise.all(Se.map(async(tt)=>{let Oe=await ti[tt](T,_);if(!Oe?.id)return;let ct=tt==="workload"?Oe.derivedEntitlements:tt==="user"||tt==="customer"?sr(T,tt):void 0;return{subject:Oe,subjectType:tt,subjectId:Oe.id,derivedEntitlements:ct}}))).filter((tt)=>tt!==void 0);if(me.length===0)return ir(_,void 0,"unauthenticated",void 0,le);let ze=async(tt)=>{let Oe=_.authz.accessIndex;if(!Oe?.isSubjectDisabled)return!1;return Oe.isSubjectDisabled(tt.subjectId,tt.subjectType)},Je=async(tt)=>{if(ye){let Oe=ye(tt);if(Oe&&Oe.length>0){if(await ze(tt))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:Oe}}}}if(ge){let Oe=ge(tt);if(Oe&&Oe.length>0){if(await ze(tt))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"claims",matchedIds:Oe.map((ct)=>ct.target),matchedClaims:[...new Set(Oe.map((ct)=>ct.claim))],roots:[...new Set(Oe.map((ct)=>ct.root).filter((ct)=>Boolean(ct)))]}}}}return X(tt)},{matched:Qe,outcomes:ut}=await oi(me,Je,(tt,Oe)=>{_.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:tt.subjectId,subjectType:tt.subjectType,error:Oe instanceof Error?Oe.message:String(Oe),...le()})});if(Qe){if(Qe.decision.metadata?.reason==="claims")_.log.info("authz.claims_honor",{"ion.operation":"authz.claims_honor","ion.outcome":"allow",subject:Qe.principal.subjectId,subjectType:Qe.principal.subjectType,matchedIds:Qe.decision.metadata.matchedIds,matchedClaims:Qe.decision.metadata.matchedClaims,roots:Qe.decision.metadata.roots,...le()});return ir(_,Qe.principal,"ok",Qe.decision,le)}let st=ut.length>0&&ut.every((tt)=>{let Oe=tt.decision.metadata?.reason;return Oe==="access_index_not_configured"||Oe==="error"}),Ne=ut[0],Ve=st?"not_configured":"forbidden";return ir(_,Ne?.principal,Ve,Ne?.decision,le)}async function ai(T,_,j,X,le,ge="any"){return zt(T,_,ge,(ye)=>_.authz.has(ye.subjectId,j,X,le,ye.subjectType),()=>({targetType:j,target:lt(X),resource:le?lt(le):void 0}),fn([{targetType:j,id:lt(X),resource:le?lt(le):void 0}],"any"),j==="permission"&&!le?jn(_,[lt(X)],"any"):void 0)}async function ci(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasPermission(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"permission",target:lt(j),resource:X?lt(X):void 0}),fn([{targetType:"permission",id:lt(j),resource:X?lt(X):void 0}],"any"),X?void 0:jn(_,[lt(j)],"any"))}async function ui(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasRole(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"role",target:lt(j),resource:X?lt(X):void 0}),fn([{targetType:"role",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function di(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasGroup(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"group",target:lt(j),resource:X?lt(X):void 0}),fn([{targetType:"group",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function li(T,_,j,X="any"){let le=j.map((ye)=>({targetType:ye.targetType,id:lt(ye.target),resource:ye.resource?lt(ye.resource):void 0})),ge=j.filter((ye)=>!ye.resource&&ye.targetType==="permission").map((ye)=>lt(ye.target));return zt(T,_,X,(ye)=>_.authz.hasAny(ye.subjectId,j,ye.subjectType),()=>({targets:j.map((ye)=>`${ye.targetType}:${lt(ye.target)}`)}),le.length>0?fn(le,"any"):void 0,ge.length>0?jn(_,ge,"any"):void 0)}async function pi(T,_,j,X="any"){let le=j.map((Se)=>({targetType:Se.targetType,id:lt(Se.target),resource:Se.resource?lt(Se.resource):void 0})),ge=j.length>0&&j.every((Se)=>!Se.resource&&Se.targetType==="permission"),ye=j.map((Se)=>lt(Se.target));return zt(T,_,X,(Se)=>_.authz.hasAll(Se.subjectId,j,Se.subjectType),()=>({targets:j.map((Se)=>`${Se.targetType}:${lt(Se.target)}`)}),le.length>0?fn(le,"all"):void 0,ge?jn(_,ye,"all"):void 0)}async function mi(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(or(le,[j],"any")),()=>({scope:j}))}async function fi(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(or(le,j,"any")),()=>({scopes:j}))}async function gi(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(or(le,j,"all")),()=>({scopes:j}))}function kt(T){return typeof T==="string"&&T.length>0?T:void 0}function Zr(T){let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}var Qr={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:Zr},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:Zr},microsoft:{flow:"id_token",authority:"https://login.microsoftonline.com/common/v2.0",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(T)=>{let _=kt(T.email)??kt(T.preferred_username);return{sub:String(T.sub??T.oid??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}},apple:{flow:"id_token",authorizationUrl:"https://appleid.apple.com/auth/authorize",tokenUrl:"https://appleid.apple.com/auth/token",jwksUri:"https://appleid.apple.com/auth/keys",scope:"openid email name",extraAuthParams:{response_mode:"form_post"},branding:{displayName:"Apple",colors:{light:"#000000",dark:"#ffffff"},url:"https://appleid.apple.com"},mapClaims:(T)=>{let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:_}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(T)=>({sub:String(T.id??T.node_id??""),email:kt(T.email),name:kt(T.name)??kt(T.login),userName:kt(T.login),avatar:kt(T.avatar_url)})}};function ar(T){if(T==="magic-link")return;return Qr[T]}function Ln(T,_){if(_.type==="magic-link")return;let j=ar(_.type);if(!j)return;return{name:T,type:_.type,flow:j.flow,authority:_.authority??j.authority,authorizationUrl:_.authorizationUrl??j.authorizationUrl,tokenUrl:_.tokenUrl??j.tokenUrl,jwksUri:_.jwksUri??j.jwksUri,userInfoUrl:_.userInfoUrl??j.userInfoUrl,scope:_.scope??j.scope,clientId:_.clientId,clientSecret:_.clientSecret,extraAuthParams:j.extraAuthParams,branding:{...j.branding,..._.branding},mapClaims:j.mapClaims,config:_}}function cr(T){return{...ar(T.type)?.branding??{displayName:T.type},...T.branding}}function ur(T){if(!T)return[];return Object.entries(T).filter(([,_])=>_.enabled!==!1).map(([_,j],X)=>({name:_,config:j,index:X})).sort((_,j)=>{let X=_.config.order??Number.MAX_SAFE_INTEGER,le=j.config.order??Number.MAX_SAFE_INTEGER;if(X!==le)return X-le;return _.index-j.index}).map(({name:_,config:j})=>({name:_,config:j}))}var yi=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;function Nn(T){if(T===void 0)return;let _=T.trim().toLowerCase();if(!yi.test(_))throw Error(`Invalid cookiesDomain "${T}": expected a hostname such as "app.example.com" without a scheme, port, path, or leading dot.`);return _}function Zt(T){return T?` Domain=${T};`:""}var es=4000;function hi(T){return`Expires=${T.toUTCString()}`}function ts(T){return`Path=${T.path};${Zt(T.domain)}${T.secure?" Secure;":""} SameSite=${T.sameSite};`}function pr(T,_,j,X){if(_.length>es)throw Error(`Display cookie ${T} value is ${_.length} bytes; the limit is ${es}.`);return`${T}=${_}; ${hi(j)}; ${ts(X)}`}function Bt(T,_){return`${T}=; Max-Age=0; ${ts(_)}`}function dr(T){if(!T)return;let _=T instanceof Date?T:new Date(T);return Number.isNaN(_.getTime())?void 0:_}function lr(T){return!T||T.getTime()>Date.now()}async function ki(T,_,j){let X=T.envelope.kind??"session";if(X==="discovered"){let Se=dr(T.envelope.expiresAt);return{...T,kind:X,live:Boolean(Se&&lr(Se))}}let le=_[`${T.prefix}.session`];if(!le)return{...T,kind:X,live:!1};let ge=await j.get(le);if(!ge||ge.authType!=="sso"&&ge.authType!=="ciam")return{...T,kind:X,live:!1};let ye=dr(ge.expiresAt);return{...T,kind:X,live:lr(ye),...ye?{sessionExpiresAt:ye}:{}}}function gn(T,_,j){let X=U(_);return T?.includes(`${X}=`)?[Bt(X,j)]:[]}function ns(T,_,j,X,le){let ge=[...T.filter((ze)=>ze.kind==="session").slice(0,j),...T.filter((ze)=>ze.kind==="discovered").slice(0,X)],ye=le?le(T,{max:j,maxDiscovered:X}):ge,Se=[...ye.filter((ze)=>ze.kind==="session").slice(0,j),...ye.filter((ze)=>ze.kind==="discovered").slice(0,X)];if(Se.some((ze)=>ze.name===_))return Se;let he=T.find((ze)=>ze.name===_);if(!he)return Se;return[...[he,...Se.filter((ze)=>ze.kind==="session")].slice(0,j),...Se.filter((ze)=>ze.kind==="discovered")]}async function An(T){let _=U(T.cookiesPrefix),j=T.attr;if(T.displayCookie?.enabled!==!0)return gn(T.cookieHeader,T.cookiesPrefix,j);if(!T.sessionStore)return[];let X=m(T.user,T.projector),le={v:W,...T.tenantId?{tenantId:T.tenantId}:{},authType:T.authType,expiresAt:T.expiresAt.toISOString(),user:X},ge={name:_,prefix:T.cookiesPrefix,envelope:le,kind:"session",sessionExpiresAt:T.expiresAt,live:!0},ye=re(T.cookieHeader),Se=T.sessionStore,he=await Promise.all(B(T.cookieHeader).filter((Ve)=>Ve.name!==_).map((Ve)=>ki(Ve,ye,Se))),me=[ge,...he.filter((Ve)=>Ve.live&&Ve.kind==="session")].sort((Ve,tt)=>P(Ve.sessionExpiresAt?.toISOString()??Ve.envelope.expiresAt,tt.sessionExpiresAt?.toISOString()??tt.envelope.expiresAt)),ze=T.displayCookie.discovered?.enabled===!0?he.filter((Ve)=>Ve.live&&Ve.kind==="discovered"&&(!T.tenantId||Ve.envelope.tenantId!==T.tenantId)).sort((Ve,tt)=>P(Ve.envelope.expiresAt,tt.envelope.expiresAt)):[],Je=[...me,...ze],Qe=te(T.displayCookie?.max),ut=V(T.displayCookie.discovered?.max),st=new Set(ns(Je,_,Qe,ut,T.trim).map((Ve)=>Ve.name)),Ne=[pr(_,z(le),T.expiresAt,j)];for(let Ve of he)if(!st.has(Ve.name))Ne.push(Bt(Ve.name,j));return Ne}function Si(T){let _=re(T.cookieHeader),j=Object.keys(_).filter((Ne)=>Ne.startsWith(`${ee}.`)&&Ne.endsWith(".profile"));if(!(T.displayCookie?.enabled===!0&&T.displayCookie.discovered?.enabled===!0))return j.map((Ne)=>Bt(Ne,T.attr));let le=T.now??new Date,ge=ne(T.displayCookie?.discovered?.ttlSeconds),ye=new Date(le.getTime()+ge*1000),Se=V(T.displayCookie?.discovered?.max),he=B(T.cookieHeader),me=new Set(he.filter((Ne)=>(Ne.envelope.kind??"session")==="session").flatMap((Ne)=>Ne.envelope.tenantId?[Ne.envelope.tenantId]:[])),ze=new Map;for(let Ne of he){if(Ne.envelope.kind!=="discovered"||!Ne.envelope.tenantId)continue;let Ve=dr(Ne.envelope.expiresAt);if(Ve&&lr(Ve)&&!me.has(Ne.envelope.tenantId))ze.set(Ne.envelope.tenantId,Ne.envelope)}let Je=m(T.user,T.projector);for(let Ne of T.tenants){let Ve=Ne.tenantId.trim();if(!Ve||me.has(Ve))continue;ze.set(Ve,{v:W,kind:"discovered",tenantId:Ve,authType:T.authType,expiresAt:ye.toISOString(),user:Je,...Ne.tenantName?{tenantName:Ne.tenantName}:{}})}let Qe=[...ze.values()].sort((Ne,Ve)=>P(Ne.expiresAt,Ve.expiresAt)).slice(0,Se),ut=new Set(Qe.map((Ne)=>G(Ne.tenantId??""))),st=Qe.map((Ne)=>pr(G(Ne.tenantId??""),z(Ne),new Date(Ne.expiresAt),T.attr));for(let Ne of j)if(!ut.has(Ne))st.push(Bt(Ne,T.attr));return st}var hr=60000,ss=86400000,is=600000,fr=256,It=new Map;function wi(T){if(typeof T?.ttlMs==="number"&&Number.isFinite(T.ttlMs))is=Math.min(Math.max(T.ttlMs,hr),ss);if(typeof T?.maxEntries==="number"&&Number.isFinite(T.maxEntries)){fr=Math.max(1,Math.floor(T.maxEntries));while(It.size>fr){let _=It.keys().next().value;if(_===void 0)break;It.delete(_)}}}function rs(T,_){It.delete(T),It.set(T,_);while(It.size>fr){let j=It.keys().next().value;if(j===void 0)break;It.delete(j)}}var In=new Map,gr=()=>Date.now();function bi(T){gr=T??(()=>Date.now())}var yr={};function Ci(T){yr=T??{}}function vi(T){if(!T)return;if(/\bno-store\b/i.test(T))return hr;let _=/max-age\s*=\s*(\d+)/i.exec(T);if(!_)return;let j=Number(_[1]);return Number.isFinite(j)?j*1000:void 0}function Ri(T){let j=vi(T)??is;return Math.min(Math.max(j,hr),ss)}async function kr(T,_=3,j=1000,X=30000,le){let ge=Error("Placeholder Error");for(let ye=0;ye<=_;ye++)try{return await T()}catch(Se){if(ge=Se instanceof Error?Se:Error(String(Se)),Se instanceof Error&&Se.message.includes("400"))throw Se;if(ye===_)throw ge;let he=Math.min(j*2**ye,X),me=Math.random()*0.1*he;await new Promise((ze)=>setTimeout(ze,he+me)),le?.warn(`Retry attempt ${ye+1} after ${he+me}ms delay`)}throw ge}async function Tn(T,_,j){let X=It.get(T);if(!j?.forceRefresh&&X&&X.expiresAt>gr())return rs(T,X),X.jwks;let le=In.get(T);if(le)return le;let ge=(async()=>{try{return await kr(async()=>{let ye=await fetch(T,{headers:i});if(!ye.ok){let me=await F(ye);throw _?.warn("JWKS endpoint returned an error",{"ion.operation":"jwks.fetch","ion.outcome":"degraded",reason:"upstream_error",status:ye.status,contentType:me.contentType,excerpt:me.excerpt}),Error(`Failed to fetch JWKS (${ye.status})`)}let Se=await a(ye,{log:_,operation:"jwks.fetch"}),he=Ri(ye.headers.get("cache-control"));return rs(T,{jwks:Se,expiresAt:gr()+he,importedKeys:new Map}),Se},yr.maxRetries,yr.baseDelayMs,void 0,_)}catch(ye){let Se=It.get(T);if(Se)return _?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),Se.jwks;throw ye}finally{In.delete(T)}})();return In.set(T,ge),ge}function Ai(T){if(T){It.delete(T),In.delete(T);return}It.clear(),In.clear()}async function Ii(T,_,j){return(await os(T,_,j)).jwk}async function os(T,_,j){if(!_?.trim())throw Error("JWT header missing kid");await Tn(T,j);let X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!le)await Tn(T,j,{forceRefresh:!0}),X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!X||!le)throw Error("Public key not found");return{jwk:le,entry:X}}async function Sr(T,_,j,X,le){let{jwk:ge,entry:ye}=await os(T,_,le),Se=`${_}\x00${j}`,he=ye.importedKeys.get(Se);if(he)return he;let me=X(ge);return me.catch(()=>{if(ye.importedKeys.get(Se)===me)ye.importedKeys.delete(Se)}),ye.importedKeys.set(Se,me),me}async function Ti(T,_){let j=T.keys.find((X)=>X.kid===_);if(!j)throw Error("Public key not found");return as(j)}function as(T){return crypto.subtle.importKey("jwk",{kty:T.kty,n:T.n,e:T.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function xi(T,_,j){return Sr(T,_,"rs256",as,j)}var mr={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 wr(T,_,j,X){if(typeof j!=="string"||!(j in mr))throw Error(`Unsupported JWT alg "${String(j)}" (allowed: ${Object.keys(mr).join(", ")})`);let le=mr[j];return{key:await Sr(T,_,`oidc:${j}`,(ye)=>{if(ye.kty!==le.kty)throw Error(`JWK type "${ye.kty}" does not match token alg "${j}"`);if(le.kty==="EC"){let Se=ye;if(Se.crv!==le.crv)throw Error(`JWK curve "${String(Se.crv)}" does not match token alg "${j}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:Se.crv,x:Se.x,y:Se.y},le.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:ye.kty,n:ye.n,e:ye.e},le.importParams,!1,["verify"])},X),algorithm:le.verifyParams}}function _t(T=32){let _=new Uint8Array(T);return crypto.getRandomValues(_),Array.from(_,(j)=>j.toString(16).padStart(2,"0")).join("").substring(0,T)}function $n(T){let _="";return T.forEach((j)=>{_+=String.fromCharCode(j)}),btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ds(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.padEnd(_.length+(4-_.length%4)%4,"="),X=atob(j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function cs(T){let _=new TextDecoder().decode(ds(T));return JSON.parse(_)}async function Pn(T){let _=new TextEncoder().encode(T),j=await crypto.subtle.digest("SHA-256",_);return $n(new Uint8Array(j))}function vr(T){let _=new URL(T.authorizationUrl);if(_.searchParams.set("client_id",T.clientId),_.searchParams.set("redirect_uri",T.redirectUri),_.searchParams.set("response_type","code"),_.searchParams.set("scope",T.scope),_.searchParams.set("state",T.state),T.codeChallenge)_.searchParams.set("code_challenge",T.codeChallenge),_.searchParams.set("code_challenge_method","S256");if(T.nonce)_.searchParams.set("nonce",T.nonce);for(let[j,X]of Object.entries(T.extraParams??{}))_.searchParams.set(j,X);return _.toString()}async function Rr(T){let _=new URLSearchParams;if(_.append("grant_type","authorization_code"),_.append("code",T.code),_.append("redirect_uri",T.redirectUri),_.append("client_id",T.clientId),T.clientSecret)_.append("client_secret",T.clientSecret);if(T.codeVerifier)_.append("code_verifier",T.codeVerifier);let j=await fetch(T.tokenUrl,{method:"POST",headers:{...h,...i},body:_.toString()}),X=await a(j,{log:T.log,operation:"oidc.token.exchange"});if(!j.ok){let le=X,ge=le.error==="invalid_client"&&!T.clientSecret;throw T.log?.error(ge?"OIDC authorization-code exchange failed: no client_secret was configured; the provider may require a confidential client":"OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":j.status,oidc_error:le.error,...ge?{client_auth:"none"}:{}}),Error(`Token exchange failed: ${le.error||j.statusText} - ${le.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var ls=60;function sn(T){return T.trim().replace(/\/$/,"")}var br="9188040d-6c67-4c5b-b112-36a304b66dad",Pi=new Set(["common","organizations","consumers"]),Ui=/^https:\/\/login\.microsoftonline\.com\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/v2\.0$/i;function Ar(T){let _=/^https:\/\/login\.microsoftonline\.com\/([^/]+)(?:\/v2\.0)?$/i.exec(sn(T));return _?Pi.has(_[1].toLowerCase()):!1}function Wn(T){let _=Ui.exec(sn(T));return _?_[1].toLowerCase():void 0}function ps(T){let _=Wn(T.iss);if(!_)return!1;if(T.tid!==void 0){if(typeof T.tid!=="string"||T.tid.toLowerCase()!==_)return!1}let j=T.allowedTenants??"any";if(j==="any")return!0;if(j==="consumers")return _===br;if(!Array.isArray(j)||j.length===0)return!1;return j.some((X)=>{let le=X.trim().toLowerCase();if(le==="consumers")return _===br;return le===_})}function ms(T){let{claims:_,audience:j}=T,X=sn(T.issuer),le=T.nowSec??Math.floor(Date.now()/1000),ge=T.clockSkewSec??ls,ye=_.iss;if(typeof ye!=="string")throw Error("ID token issuer mismatch");let Se=T.issuerPolicy??{mode:"exact"};if(!(sn(ye)===X||Se.mode==="microsoft-tenant"&&ps({iss:ye,tid:_.tid,allowedTenants:Se.allowedTenants})))throw Error("ID token issuer mismatch");let me=_.aud,ze=Array.isArray(me)?me.includes(j):typeof me==="string"&&me===j,Je=typeof _.azp==="string"&&_.azp===j;if(!ze&&!Je)throw Error("ID token audience mismatch");if(typeof _.exp!=="number")throw Error("ID token missing exp");if(_.exp<le-ge)throw Error("ID token expired");if(T.expectedNonce!==void 0){if(_.nonce!==T.expectedNonce)throw Error("ID token nonce mismatch")}}async function fs(T,_,j){let X=T.split(".");if(X.length!==3)throw Error("Invalid JWT");let le=cs(X[0]),ge=cs(X[1]),ye=ds(X[2]),{key:Se,algorithm:he}=await wr(_,le.kid,le.alg,j),me=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(he,Se,ye,me))throw Error("Invalid JWT signature");return{header:le,payload:ge}}async function Qt(T){let{payload:_}=await fs(T.idToken,T.jwksUri,T.log);return ms({claims:_,issuer:T.issuer,issuerPolicy:T.issuerPolicy,audience:T.audience,clockSkewSec:T.clockSkewSec,expectedNonce:T.expectedNonce}),_}var Ei="http://schemas.openid.net/event/backchannel-logout";async function Ir(T){let{payload:_}=await fs(T.logoutToken,T.jwksUri,T.log),j=sn(T.issuer),X=_.iss;if(typeof X!=="string"||sn(X)!==j)throw Error("Logout token issuer mismatch");let le=_.aud,ge=Array.isArray(le)?le.includes(T.audience):typeof le==="string"&&le===T.audience,ye=typeof _.azp==="string"&&_.azp===T.audience;if(!ge&&!ye)throw Error("Logout token audience mismatch");if(_.nonce!=null)throw Error("Logout token must not contain a nonce");let Se=_.events;if(!(typeof Se==="object"&&Se!==null&&!Array.isArray(Se)&&Object.hasOwn(Se,Ei)))throw Error("Logout token missing back-channel logout event");let me=typeof _.sid==="string"&&_.sid.length>0,ze=typeof _.sub==="string"&&_.sub.length>0;if(!me&&!ze)throw Error("Logout token missing sid and sub");if(typeof _.exp==="number"){let Je=Math.floor(Date.now()/1000),Qe=T.clockSkewSec??ls;if(_.exp<Je-Qe)throw Error("Logout token expired")}return _}var Di=3600000,Mi=60000,Oi=86400000,_i=256,Gt=new Map,xn=new Map;function us(T,_){Gt.delete(T),Gt.set(T,_);while(Gt.size>_i){let j=Gt.keys().next().value;if(j===void 0)break;Gt.delete(j)}}var Cr=()=>Date.now();function ji(T){Cr=T??(()=>Date.now())}function Li(T){if(T){Gt.delete(T),xn.delete(T);return}Gt.clear(),xn.clear()}function Ni(T){let _=T?/max-age\s*=\s*(\d+)/i.exec(T):null,j=_?Number(_[1]):Number.NaN,X=Number.isFinite(j)?j*1000:Di;return Math.min(Math.max(X,Mi),Oi)}async function Vn(T){let _=Gt.get(T);if(_&&_.expiresAt>Cr())return us(T,_),_.endpoints;let j=xn.get(T);if(j)return j;let X=(async()=>{try{let le=T.replace(/\/$/,""),ge=await fetch(`${le}/.well-known/openid-configuration`,{headers:i});if(!ge.ok)throw Error(`OIDC discovery failed for ${T} with status ${ge.status}`);let ye=await a(ge),Se={authorizationUrl:typeof ye.authorization_endpoint==="string"?ye.authorization_endpoint:void 0,tokenUrl:typeof ye.token_endpoint==="string"?ye.token_endpoint:void 0,jwksUri:typeof ye.jwks_uri==="string"?ye.jwks_uri:void 0,userInfoUrl:typeof ye.userinfo_endpoint==="string"?ye.userinfo_endpoint:void 0};return us(T,{endpoints:Se,expiresAt:Cr()+Ni(ge.headers.get("cache-control"))}),Se}catch(le){let ge=Gt.get(T);if(ge)return ge.endpoints;throw le}finally{xn.delete(T)}})();return xn.set(T,X),X}async function Tr(T,_){let j=await fetch(T,{headers:{Authorization:`Bearer ${_}`,...i,"User-Agent":"ionite-ciam"}});if(!j.ok)throw Error(`UserInfo request failed with status ${j.status}`);return await a(j)}function $i(T){let _=T.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),j=atob(_),X=new Uint8Array(j.length);for(let le=0;le<j.length;le++)X[le]=j.charCodeAt(le);return X}async function xr(T){let _=Math.floor(Date.now()/1000),j={alg:"ES256",kid:T.keyId,typ:"JWT"},X={iss:T.teamId,iat:_,exp:_+(T.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:T.clientId},le=$n(new TextEncoder().encode(JSON.stringify(j))),ge=$n(new TextEncoder().encode(JSON.stringify(X))),ye=`${le}.${ge}`,Se=await crypto.subtle.importKey("pkcs8",$i(T.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),he=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},Se,new TextEncoder().encode(ye));return`${ye}.${$n(new Uint8Array(he))}`}function Wi(T){for(let _=0;_<T.length;_++){let j=T.charCodeAt(_);if(j<=31||j===127)return!0}return!1}function Vi(T,_){let j=null;try{j=new URL(T,_)}catch{j=null}let X="";try{X=new URL(_).origin}catch{X=""}return{candidate:T,url:j,requestOrigin:X}}function gs(T,_,j){let X=Vi(T,j),le=!1;for(let ge of _){let ye=ge(X);if(ye==="deny")return!1;if(ye==="allow")le=!0}return le}function ys(){return({candidate:T,url:_})=>{if(Wi(T))return"deny";if(T.includes("\\"))return"deny";if(T.startsWith("//"))return"deny";if(!_)return"deny";if(_.protocol!=="http:"&&_.protocol!=="https:")return"deny";if(_.username||_.password)return"deny";return"abstain"}}function hs(){return({candidate:T})=>T.startsWith("/")&&!T.startsWith("//")&&!T.startsWith("/\\")?"allow":"abstain"}function ks(){return({url:T,requestOrigin:_})=>T&&_&&T.origin===_?"allow":"abstain"}function qi(...T){let _=new Set(T.map((j)=>{try{return new URL(j).origin}catch{return j}}));return({url:j})=>j&&_.has(j.origin)?"allow":"abstain"}function zi(...T){let _=T.map((j)=>j.toLowerCase());return({url:j})=>{if(!j)return"abstain";let X=j.hostname.toLowerCase();for(let le of _)if(le.startsWith(".")){if(X===le.slice(1)||X.endsWith(le))return"allow"}else if(X===le)return"allow";return"abstain"}}function Pr(){return[ys(),hs(),ks()]}function Ss(T,_,j){if(!T)return!1;return gs(T,_,j)}function Ur(T,_){if(!T)return _.fallback;return gs(T,_.rules,_.requestUrl)?T:_.fallback}var Bi={rules:Pr(),fallback:"/"};function Gi(T,_,j="redirect"){let X=new URL(T.url).searchParams.get(j)??void 0;return Ss(X,_.rules,T.url)?{redirect:X}:void 0}function Ki(T,_){let j=T.context;return Ur(j?.redirect,{rules:_.rules,fallback:_.fallback,requestUrl:T.request.url})}function en(T,_,j){if(T instanceof Response)return{response:T};if(typeof T==="string")return{location:Ur(T,{rules:Pr(),fallback:_,requestUrl:j})};return{location:_}}function on(T,_){if(_.length===0)return T;let j=new Headers(T.headers);for(let X of _)j.append("Set-Cookie",X);return new Response(T.body,{status:T.status,statusText:T.statusText,headers:j})}var qn="ciam",Ji="id_token",Hi="access_token";function Fi(T,_,j,X,le,ge){if(!j&&!X)return;let ye=new WeakMap,Se={...j,...X},he={...Se,magicLinkTtl:Se.magicLinkTtl??3600,sessionTtl:Se.sessionTtl??86400,cookiesSecure:Se.cookiesSecure!==void 0?Se.cookiesSecure:!0,cookiesSameSite:Se.cookiesSameSite!==void 0?Se.cookiesSameSite:"Strict",cookiesPrefix:Se.cookiesPrefix??(Se.ciamId?`ion.ciam.${Se.ciamId}`:"ion.ciam"),cookiesPath:Se.cookiesPath??"/",cookiesDomain:Nn(Se.cookiesDomain)};function me(){if(!he.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return he.sessionStore}function ze(){me()}let Je=T.callbackParams??l(oe("ionite.ciam")),Qe=T.idTokenClaims??l(y("ionite.ciam")),ut=T.tokenResponse??l(ie("ionite.ciam"));function st(fe=32){let we=new Uint8Array(fe);return crypto.getRandomValues(we),Array.from(we,(Te)=>Te.toString(16).padStart(2,"0")).join("").substring(0,fe)}function Ne(fe,we,Te,Ae=he.cookiesSameSite??"Strict"){if(!he)throw Error("ionite CIAM Manager not initialized");if(fe=`${he.cookiesPrefix}.${fe}`,typeof we!=="string")we=btoa(JSON.stringify(we));let xe;if(Te instanceof Date)xe=`Expires=${Te.toUTCString()}`;else if(typeof Te==="number")xe=`Max-Age=${Te}`;else throw Error("Invalid expires type",Te);if(we.length>4000)throw Error(`Error setting cookie: ${fe}. Cookie length is: ${we.length}`);return`${fe}=${we}; ${xe}; Path=${he.cookiesPath};${Zt(he.cookiesDomain)} HttpOnly;${he.cookiesSecure?" Secure;":""} SameSite=${Ae};`}function Ve(fe){if(!he)throw Error("ionite CIAM Manager not initialized");return`${he.cookiesPrefix}.${fe}=; Max-Age=0; Path=${he.cookiesPath};${Zt(he.cookiesDomain)} HttpOnly;${he.cookiesSecure?" Secure;":""} SameSite=${he.cookiesSameSite};`}function tt(fe,we,Te=!1){if(!he)throw Error("ionite CIAM Manager not initialized");let Ae=we.headers.get("cookie");if(!Ae)return null;let xe=`${he.cookiesPrefix}.${fe}`,qe=Ae.split(";").find((ke)=>ke.trim().startsWith(`${xe}=`));if(!qe)return null;let We=qe.indexOf("="),ve=qe.substring(We+1).trim();if(!Te)return ve;try{let ke=atob(ve);return JSON.parse(ke)}catch(ke){return _.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:xe},ke),null}}function Oe(fe){return`cstate_${fe}`}async function ct(fe,we,Te,Ae){let xe=await he.afterLogin?.({...we,request:fe,context:Te,displayCookie:he.displayCookie,displayCookieAttributes:bt()}),qe=en(xe,"/",fe.url);if(qe.response)return on(qe.response,Ae.map(([,We])=>We));return new Response(we.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",qe.location],...Ae]})}function ft(fe,we){return["Set-Cookie",Ne("session",fe,we)]}function bt(){return{path:he.cookiesPath??"/",domain:he.cookiesDomain,secure:he.cookiesSecure!==!1,sameSite:he.cookiesSameSite??"Strict"}}function gt(){return[["Set-Cookie",Ve("session")],["Set-Cookie",Bt(`${he.cookiesPrefix}.profile`,bt())]]}function Rt(fe){if(he.displayCookie?.enabled===!0)return[];return gn(fe.headers.get("cookie"),he.cookiesPrefix??"ion.ciam",bt()).map((we)=>["Set-Cookie",we])}async function Tt(fe,we,Te){return(await An({cookieHeader:fe.headers.get("cookie"),sessionStore:he.sessionStore,cookiesPrefix:he.cookiesPrefix??"ion.ciam",authType:"ciam",tenantId:he.tenantId,expiresAt:Te,user:we,projector:he.displayUser,displayCookie:he.displayCookie,trim:he.trimDisplayCookies,attr:bt()})).map((xe)=>["Set-Cookie",xe])}function Ot(fe){if(!fe)return;if(fe instanceof Date)return fe;let we=new Date(fe);return Number.isNaN(we.getTime())?void 0:we}async function wn(fe){let we=tt("session",fe);if(!we)return;let Te=await me().get(we);if(Te&&he.tenantId&&Te.tenantId&&Te.tenantId!==he.tenantId)return;if(Te?.authType!=="ciam")return;let Ae=Ot(Te.expiresAt);if(Ae&&Date.now()>Ae.getTime()){await me().delete(we);return}return Te}async function Jt(fe){if(!he)throw Error("ionite CIAM Manager not initialized");ze();let we=ye.get(fe);if(we)return we;let Te=bn(fe);return ye.set(fe,Te),Te}async function bn(fe){try{let we=await wn(fe);if(!we?.claims?.sub)return{status:"unauthenticated"};return Rn(fe,"customer",we.entitlements),{status:"authenticated",value:xt(we.claims)}}catch(we){return _.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},we),{status:"degraded",error:we instanceof Error?we:void 0}}}async function dn(fe){let we=await Jt(fe);return we.status==="authenticated"?we.value:void 0}async function Ht(fe){if(!he)throw Error("ionite CIAM Manager not initialized");ze();let we;try{we=await dn(fe)}catch{we=void 0}let Te=await he.beforeLogout?.({request:fe,user:we});try{let Ce=tt("session",fe);if(Ce)await me().delete(Ce)}catch(Ce){_.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Ce)}let Ae=gt(),xe=await he.afterLogout?.({request:fe,context:Te}),qe=en(xe,"/",fe.url);if(qe.response)return on(qe.response,Ae.map(([,Ce])=>Ce));let We=qe.location??"/",ve=fe.headers.get("accept");if(ve?.includes(s)||ve?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:We}),{status:200,headers:[["Content-Type",s],...Ae]});return new Response("Logged out",{status:302,headers:[["Location",We],...Ae]})}function Ft(fe){return fe.id||fe.email||`ciam-${fe.userName}`}function rn(fe,we,Te){return{sub:Ft(fe),iss:qn,aud:qn,typ:Ji,exp:Math.floor(Te.getTime()/1000),iat:Math.floor(Date.now()/1000),email:fe.email,name:fe.name,preferred_username:fe.userName,picture:fe.avatar,sid:we}}function ln(fe,we,Te){return{sub:fe,iss:qn,aud:qn,typ:Hi,exp:Math.floor(Te.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:we,scope:"openid profile email"}}function xt(fe){let we=fe.exp?new Date(fe.exp*1000):new Date;return{id:fe.sub,userName:fe.preferred_username??"",name:fe.name??"",email:fe.email??"",avatar:fe.picture,userType:"customer",ciam:{profile:fe,scope:"openid profile email",tokenType:"Bearer",expires:we}}}async function pn(fe){if(!he)throw Error("ionite CIAM Manager not initialized");if(!le)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:r});if(!await le.getWorkloadIdentity(fe))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:r});let Te,Ae;try{if(!fe.headers.get("content-type")?.includes(s))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:r});let je=await fe.text(),Ue=JSON.parse(je);Ae=typeof Ue?.redirect==="string"&&Ue.redirect.length>0?Ue.redirect:void 0;let Le={userName:Ue.userName,name:Ue.name,email:Ue.email,avatar:Ue.avatar},Fe=await T.customer.validate(Le);if(Fe.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:r});Te=Fe.value}catch(Ee){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:r})}let qe=new URL(fe.url).searchParams.get("ttl"),We=qe?parseInt(qe,10):he.magicLinkTtl??3600;if(Number.isNaN(We)||We<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:r});let ve=st(32),ke=new Date(Date.now()+We*1000);if(!he.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:r});try{await he.magicLinkStore.create(ve,Te,ke)}catch(Ee){return _.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},Ee),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:r})}let Ce=new URL(fe.url),Ie=he.magicLinkLoginUrl||"/magic-link/login",Re=new URL(Ie,Ce.origin);if(Re.searchParams.set("token",ve),Ae)Re.searchParams.set("redirect",Ae);return new Response(JSON.stringify({magicLink:Re.toString(),expiresAt:ke.toISOString()}),{status:200,headers:r})}async function Yt(fe){if(!he)throw Error("ionite CIAM Manager not initialized");ze();let Te=new URL(fe.url).searchParams.get("token");if(!Te)return ct(fe,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!he.magicLinkStore)return ct(fe,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let Ae=await he.magicLinkStore.getAndDelete(Te);if(!Ae)return ct(fe,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let xe=new Date(Date.now()+(he.sessionTtl??86400)*1000),qe=st(32),We=Ft(Ae.customer),ve=rn(Ae.customer,qe,xe),ke=ln(We,qe,xe),Ce=xt(ve),Ie;try{let Ee={sid:qe,sub:We,authType:"ciam",tenantId:he.tenantId,expiresAt:xe,claims:ve,accessClaims:ke,createdAt:new Date};await me().create(Ee),Ie=Ee}catch(Ee){throw _.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},Ee),Ee}if(he.customerStore)try{let Ee=Ce.id;if(Ee){let je=new Date,Ue=await he.customerStore.get(Ee);if(Ue||he.enableJitUserProvisioning){let Le={...Ue??{},...Ce,id:Ee,tenantId:Ue?.tenantId,createdAt:Ue?.createdAt??je,updatedAt:je,userType:Ue?.userType??"customer"};await he.customerStore.upsert(Le)}}}catch(Ee){_.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},Ee)}let Re=[ft(qe,xe),...await Tt(fe,Ce,xe)];return ct(fe,{ok:!0,user:Ce,session:Ie},void 0,Re)}function Pt(fe,we=200,Te=[]){return new Response(JSON.stringify(fe),{status:we,headers:[["Content-Type",s],...Te]})}function At(fe,we){try{return new URL(fe).toString()}catch{let Te=new URL(we).origin,Ae=he.cookiesSecure?Te.replace(/^http:\/\//,"https://"):Te;return new URL(fe,Ae).toString()}}function $t(){let fe=he.customerLoginUrl||"/auth/customer/login",we=fe.includes("?")?"&":"?";return ur(he.providers).map(({name:Te,config:Ae})=>{let xe=cr(Ae);return{name:Te,type:Ae.type,displayName:xe.displayName,loginUrl:`${fe}${we}provider=${encodeURIComponent(Te)}`,iconUrl:xe.iconUrl,colors:xe.colors,url:xe.url}})}async function Wt(fe){if(!fe)return{};let{authorizationUrl:we,tokenUrl:Te,jwksUri:Ae,userInfoUrl:xe}=fe,qe=fe.authority;if(qe&&(!we||!Te||fe.flow==="id_token"&&!Ae))try{let ve=await Vn(qe);we=we??ve.authorizationUrl,Te=Te??ve.tokenUrl,Ae=Ae??ve.jwksUri,xe=xe??ve.userInfoUrl}catch(ve){_.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},ve)}return{authorizationUrl:we,tokenUrl:Te,jwksUri:Ae,userInfoUrl:xe}}function Xt(fe,we){if(fe.type!=="microsoft"||!Ar(we))return{mode:"exact"};return{mode:"microsoft-tenant",allowedTenants:fe.config.allowedTenants??"any"}}async function Ut(fe,we){let Te=mn(fe),Ae=typeof Te?.iss==="string"?Te.iss:void 0,xe=Ae?Wn(Ae):void 0;if(!xe)return we;try{let qe=await Vn(`https://login.microsoftonline.com/${xe}/v2.0`);if(qe.jwksUri)return qe.jwksUri}catch(qe){_.warn("CIAM tenant-scoped OIDC discovery failed; falling back to configured JWKS",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},qe)}return we}async function Be(fe){if(fe.type==="apple"){let{teamId:we,keyId:Te,privateKey:Ae,clientId:xe}=fe.config;if(we&&Te&&Ae&&xe)return xr({teamId:we,keyId:Te,privateKey:Ae,clientId:xe})}return fe.clientSecret}async function Xe(fe){me();let Te=new URL(fe.url).searchParams.get("provider");if(!Te)return Pt({error:"Missing required query parameter: provider"},400);let Ae=he.providers?.[Te];if(!Ae||Ae.enabled===!1||Ae.type==="magic-link")return Pt({error:`Unknown or disabled CIAM provider: ${Te}`},404);let xe=Ln(Te,Ae);if(!xe?.clientId)return Pt({error:`CIAM provider ${Te} is not fully configured`},500);let qe=await Wt(xe);if(!qe.authorizationUrl)return Pt({error:`CIAM provider ${Te} is missing an authorization endpoint`},500);let We=he.customerCallbackUrl||"/auth/customer/callback",ve=At(We,fe.url),ke=_t(),Ce=_t(64),Ie=_t(),Re=xe.flow==="id_token",Ee=Re?await Pn(Ce):void 0,je=await he.beforeLogin?.({request:fe}),Ue=vr({authorizationUrl:qe.authorizationUrl,clientId:xe.clientId,redirectUri:ve,scope:xe.scope,state:ke,codeChallenge:Ee,nonce:Ie,extraParams:xe.extraAuthParams}),Le={provider:Te,state:ke,codeVerifier:Re?Ce:void 0,nonce:Ie,redirectUri:ve,...je===void 0?{}:{context:je}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",Ue],["Set-Cookie",Ne(Oe(ke),Le,he.loginStateTtl??600,"Lax")]]})}async function Ge(fe){if(fe.method==="POST"){if((fe.headers.get("content-type")??"").includes(D)){let Te=await fe.text();return Object.fromEntries(new URLSearchParams(Te).entries())}}return Object.fromEntries(new URL(fe.url).searchParams.entries())}let Ze=!1;async function He(fe,we,Te,Ae){let xe=fe.config.claimsAsEntitlements;if(!xe?.claims?.length||fe.type==="magic-link")return;if(he.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Ze)Ze=!0,_.warn("CIAM claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.ciam.claims.incapable","ion.module":"ciam","ion.outcome":"degraded"});return}return vn({block:xe,claims:we,accessClaims:mn(Ae),subjectType:"customer",subjectId:Te,catalog:ge?.catalogView?.(),log:_})}async function Ye(fe,we,Te){let Ae=fe.mapClaims(we);if(!Ae.sub)return{ok:!1};let xe=`${fe.name}:${Ae.sub}`,qe={id:xe,userName:Ae.userName||Ae.email||xe,name:Ae.name||"",email:Ae.email||"",avatar:Ae.avatar,userType:"customer"},We=xe;if(he.customerStore){let Ee=await he.customerStore.lookup(qe)??await he.customerStore.get(xe);if(We=Ee?.id??xe,!Ee&&!he.enableJitUserProvisioning)return _.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let je=new Date,Ue={...Ee??{},...qe,id:We,tenantId:Ee?.tenantId,createdAt:Ee?.createdAt??je,updatedAt:je,userType:Ee?.userType??"customer"};await he.customerStore.upsert(Ue)}let ve=new Date(Date.now()+(he.sessionTtl??86400)*1000),ke=_t(32),Ce={sub:We,iss:fe.name,aud:fe.clientId,exp:Math.floor(ve.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Ae.email,name:Ae.name,preferred_username:Ae.userName??Ae.email,picture:Ae.avatar,sid:ke},Ie={sid:ke,sub:We,authType:"ciam",tenantId:he.tenantId,expiresAt:ve,claims:Ce,accessClaims:{sub:We,sid:ke,scope:fe.scope},entitlements:await He(fe,we,We,Te),createdAt:new Date},Re=me();try{await Re.create(Ie)}catch(Ee){if(!await Re.get(ke))throw Ee;await Re.update(ke,Ie)}return{ok:!0,claims:Ce,sid:ke,expires:ve}}async function dt(fe){me();let we,Te,Ae=(xe)=>{let qe=we?[["Set-Cookie",Ve(we)]]:[];return ct(fe,{ok:!1,error:xe},Te,qe)};try{let xe=await Ge(fe),qe=await Je.validate(xe);if(qe.issues||!qe.value)return Ae(Error("Invalid CIAM callback parameters"));let{code:We,state:ve}=qe.value;if(!ve)return Ae(Error("Missing CIAM callback state"));we=Oe(ve);let ke=tt(we,fe,!0);if(Te=ke?.context,!ke?.provider||!ke.state||ke.state!==ve)return _.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ae(Error("CIAM callback state verification failed"));let Ce=he.providers?.[ke.provider];if(!Ce)return Ae(Error("Unknown CIAM provider"));let Ie=Ln(ke.provider,Ce);if(!Ie?.clientId)return Ae(Error("CIAM provider not configured"));let Re=await Wt(Ie);if(!Re.tokenUrl)return Ae(Error("CIAM provider missing token endpoint"));let Ee=await Be(Ie),je=await Rr({tokenUrl:Re.tokenUrl,clientId:Ie.clientId,clientSecret:Ee,redirectUri:ke.redirectUri||At(he.customerCallbackUrl||"/auth/customer/callback",fe.url),code:We,codeVerifier:Ie.flow==="id_token"?ke.codeVerifier:void 0,log:_}),Ue;if(Ie.flow==="id_token"){let at=Ie.authority;if(!je.id_token||!Re.jwksUri||!at)return Ae(Error("CIAM id_token flow misconfigured"));if(!ke.nonce)return Ae(Error("CIAM callback state cookie missing nonce"));if((await ut.validate(je)).issues)return _.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ae(Error("CIAM token response validation failed"));let it=Xt(Ie,at),et=it.mode==="microsoft-tenant"?await Ut(je.id_token,Re.jwksUri):Re.jwksUri;Ue=await Qt({idToken:je.id_token,jwksUri:et,issuer:at,issuerPolicy:it,audience:Ie.clientId,expectedNonce:ke.nonce,log:_});let mt=await Qe.validate(Ue);if(!mt.issues)Ue=mt.value}else{if(!Re.userInfoUrl)return Ae(Error("CIAM provider missing userinfo endpoint"));Ue=await Tr(Re.userInfoUrl,je.access_token);let at=Ie.authority;if(je.id_token&&Re.jwksUri&&at){let pt=Xt(Ie,at),it=pt.mode==="microsoft-tenant"?await Ut(je.id_token,Re.jwksUri):Re.jwksUri,et=await Qt({idToken:je.id_token,jwksUri:it,issuer:at,issuerPolicy:pt,audience:Ie.clientId,expectedNonce:ke.nonce||void 0,log:_}),mt=typeof et.sub==="string"?et.sub:"";if(mt){if(typeof Ue.sub==="string"&&Ue.sub.length>0&&Ue.sub!==mt)return _.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ae(Error("CIAM UserInfo sub mismatch"));Ue.sub=mt}}if(typeof Ue.sub!=="string"||Ue.sub.length===0)return _.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ae(Error("CIAM UserInfo response missing sub"))}let Le=await Ye(Ie,Ue,je.access_token);if(!Le.ok)return Ae(Error("Failed to persist CIAM customer"));let Fe=xt(Le.claims);_.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:Ie.name});let rt=[["Set-Cookie",Ve(we)],ft(Le.sid,Le.expires),...await Tt(fe,Fe,Le.expires)];return ct(fe,{ok:!0,user:Fe,session:void 0},Te,rt)}catch(xe){return _.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},xe),Ae(xe)}}async function be(fe){if(!he)throw Error("ionite CIAM Manager not initialized");ze();let we=he.magicLinkUrl||"/magic-link",Te=he.magicLinkLoginUrl||"/magic-link/login",Ae=he.logoutUrl||"/auth/customer/logout",xe=he.customerLoginUrl||"/auth/customer/login",qe=he.customerCallbackUrl||"/auth/customer/callback",We=he.customerProvidersUrl||"/auth/customer/providers",ve=new URL(fe.url).pathname,ke=(Le)=>{if(!Le)return;try{return new URL(Le).pathname}catch{return Le.startsWith("/")?Le:`/${Le}`}};if(ke(we)===ve&&fe.method==="POST")return pn(fe);if(ke(Te)===ve&&fe.method==="GET")return Yt(fe);if(ke(Ae)===ve&&fe.method==="GET")return Ht(fe);if(ke(We)===ve&&fe.method==="GET")return Pt({providers:$t()});if(ke(xe)===ve&&fe.method==="GET")return Xe(fe);if(ke(qe)===ve&&(fe.method==="GET"||fe.method==="POST"))return dt(fe);return new Response("Not Found",{status:404})}async function Pe(fe){if((he.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Rt(fe)});let we=await Jt(fe);if(we.status==="degraded")return new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r});if(we.status==="unauthenticated")return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:r});let Te=Ot(we.value.ciam?.expires),Ae=he.displayCookie?.enabled===!0?Te&&!tt("profile",fe)?await Tt(fe,we.value,Te):[]:Rt(fe),xe=he.userEndpoint==="display"?m(we.value,he.displayUser):we.value;return new Response(JSON.stringify(xe),{headers:[["Content-Type",s],...Ae]})}let _e;return _e={...he,describe:()=>({module:"ciam",active:!0,ready:_e.isReady?.()??!0,magicLinkTtl:he.magicLinkTtl,loginStateTtl:he.loginStateTtl,sessionTtl:he.sessionTtl,cookies:{prefix:he.cookiesPrefix,path:he.cookiesPath,secure:he.cookiesSecure,sameSite:he.cookiesSameSite,domain:he.cookiesDomain},displayCookie:he.displayCookie,jit:{enabled:he.enableJitUserProvisioning===!0,customerStore:he.customerStore!==void 0},sessionStore:he.sessionStore!==void 0,magicLinkStore:he.magicLinkStore!==void 0,providers:Object.entries(he.providers??{}).map(([fe,we])=>({name:fe,type:we.type,enabled:we.enabled!==!1,order:we.order,branding:we.branding,authority:we.authority,authorizationUrl:we.authorizationUrl,tokenUrl:we.tokenUrl,jwksUri:we.jwksUri,userInfoUrl:we.userInfoUrl,clientId:we.clientId,scope:we.scope,...we.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...we.claimsAsEntitlements.claims],expand:we.claimsAsEntitlements.expand===!0,resources:we.claimsAsEntitlements.expand===!0&&we.claimsAsEntitlements.resources===!0,capable:he.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},loginUrl:`${he.customerLoginUrl??""}?provider=${encodeURIComponent(fe)}`})),urls:{magicLinkUrl:he.magicLinkUrl??"",magicLinkLoginUrl:he.magicLinkLoginUrl??"",customerUrl:he.customerUrl??"",customerLoginUrl:he.customerLoginUrl??"",customerCallbackUrl:he.customerCallbackUrl??"",customerProvidersUrl:he.customerProvidersUrl??"",logoutUrl:he.logoutUrl??""}}),getCustomer:dn,resolveCustomer:Jt,logout:Ht,handler:be,customerHandler:Pe,listCustomerProviders:$t},_e}async function Yi(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),_.ciam?.getCustomer(T)}async function zn(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await _.ciam?.resolveCustomer(T)??{status:"unauthenticated"}}var Xi="urn:ietf:params:scim:schemas:core:2.0:User",ws="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Zi="urn:ietf:params:scim:schemas:core:2.0:Group";function Er(T,_,j){let le=(_==="group"?T.resources:void 0)?.map((ge)=>typeof ge==="string"?ge:ge.id).filter(Boolean);return{schemas:[Zi,e],id:T.id,externalId:T.providerId,displayName:T.displayName??T.name,members:j,[e]:{type:_,requestable:T.requestable,riskLevel:T.riskLevel??f,providerId:T.providerId,requestUrl:T.requestUrl,source:T.source,deprecated:T.deprecated,description:T.description,resources:le&&le.length>0?le:void 0,assignableSubjectTypes:T.assignableSubjectTypes,recommendedSubjectTypes:T.recommendedSubjectTypes,attributes:o(T,d)}}}function Qi(T){if(T.scimName)return T.scimName;if(!T.name)return;let[_,...j]=T.name.split(" ");return{givenName:_,familyName:j.join(" ")||void 0}}function eo(T){let _={attributes:o(T,A)};if(T.ecid!==void 0)_.ecid=T.ecid;if(T.accountClass!==void 0)_.accountClass=T.accountClass;return _.ecid!==void 0||_.accountClass!==void 0||_.attributes!==void 0?_:void 0}function to(T){return Object.keys(T.scimSchemaExtensions??{}).filter((_)=>_.startsWith("urn:")&&T.scimSchemaExtensions?.[_]!==void 0)}function Dr(T){let _=T.userName||T.email||T.id||"",j=T.emails??(T.email?[{value:T.email,primary:!0}]:[]),X=new Set([Xi]);if(T.scimEnterprise!==void 0)X.add(ws);let le=eo(T);if(le!==void 0)X.add(u);for(let ye of to(T))X.add(ye);let ge={};if(T.scimEnterprise!==void 0)ge[ws]=T.scimEnterprise;if(le!==void 0)ge[u]=le;for(let[ye,Se]of Object.entries(T.scimSchemaExtensions??{}))if(ye.startsWith("urn:")&&ye!==u&&Se!==void 0)ge[ye]=Se;return{schemas:Array.from(X),id:T.id,externalId:T.externalId,userName:_,displayName:T.displayName??T.name??_,name:Qi(T),nickName:T.nickName,profileUrl:T.avatar,title:T.title,userType:T.userType,preferredLanguage:T.preferredLanguage,locale:T.locale,timezone:T.timezone,active:T.active??!0,emails:j,phoneNumbers:T.phoneNumbers,ims:T.ims,photos:T.photos,addresses:T.addresses,groups:T.groups,entitlements:T.entitlements,roles:T.roles,x509Certificates:T.x509Certificates,meta:{resourceType:"User",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()},...ge}}function Mr(T){return{schemas:[b],id:T.id,externalId:T.externalId,userName:T.clientId??T.id,displayName:T.displayName??T.clientId??T.id,description:T.description,active:T.active??!0,ecid:T.ecid,providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,v),meta:{resourceType:"Workload",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function Or(T){return{schemas:[C],id:T.id,externalId:T.externalId??T.id,userName:T.userName??T.email??T.id,displayName:T.displayName??T.name??T.userName??T.id,active:T.active??!0,emails:T.emails??(T.email?[{value:T.email,primary:!0}]:void 0),providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,I),meta:{resourceType:"Customer",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function yn(T){return{enabled:T?.enabled!==!1,assignment:T?.assignment??"app",delta:T?.delta}}var no="urn:ietf:params:scim:api:messages:2.0:ListResponse",$r="urn:ietf:params:scim:api:messages:2.0:Error",Wr="urn:ietf:params:scim:schemas:core:2.0:User",Mn="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Vr="urn:ietf:params:scim:schemas:core:2.0:Group",ro="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",Bn="urn:ietf:params:scim:schemas:core:2.0:ResourceType",an="urn:ietf:params:scim:schemas:core:2.0:Schema",so="00000000000000000000000000000000";function io(T){let _={timestamp:new Date().toISOString()};if(T)_.actor=T;try{let le=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),ge=le?.traceId;if(ge&&ge!==so){if(_.traceId=ge,le?.spanId)_.spanId=le.spanId}}catch{}return _}class On extends Error{constructor(T){super(T);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,On.prototype)}}async function xs(T,_,j,X){let le=j.subjectType;if(!g.includes(le))throw new On(`Cannot grant ${j.targetType} "${n(j.target)}" to a "${le}" principal: only [${g.join(", ")}] principals are assignable on this platform.`);let ge=q(_,T);if(!ge&&!X)return;let ye=n(j.target),Se;if(X)Se=await X.getNode(j.targetType,ye);else if(ge)Se=await(j.targetType==="group"?ge.groups:j.targetType==="role"?ge.roles:ge.permissions).get(ye);if(!Se)return;let he=Se.assignableSubjectTypes;if(!he||he.length===0||!he.includes(le))throw new On(`Cannot grant ${j.targetType} "${ye}" to a "${le}" principal: this entitlement restricts assignment to [${(he??[]).join(", ")||"none"}].`)}async function oo(T,_){let j=N(T.codeCatalog,n(_.target));if(!j)return;if(j.kind!==_.targetType)throw Error(`Cannot grant ${_.targetType} "${j.entity.id}": code declares that id as ${j.kind}.`);if(!T.catalogStore)throw Error(`Cannot grant code entitlement "${j.entity.id}": no AccessCatalogStore is wired for materialization.`);await K(j.kind,j.entity,L(T.catalogStore,j.kind))}async function ao(T,_,j,X){await oo(T,_),await xs(T.catalogStore,T.codeCatalog,_,X);let le={..._,status:_.status??"active",provenance:_.provenance??io()};if(le.id=p(le),await T.accessStore?.grant(le),T.accessIndex&&(T.catalogStore||T.codeCatalog)){let ge=await E(le,{catalog:T.catalogStore,code:T.codeCatalog,resources:T.resources,cache:X});await T.accessIndex.materialize(le.id,ge)}return j?.push({op:"add",change:le}),le}async function En(T,_,j){let X=_.id??p(_);await T.accessStore?.revoke(_),await T.accessIndex?.removeByRoot(X),j?.push({op:"delete",change:{..._,id:X}})}async function Jn(T,_){let j=await co(T,_),X=await lo(T,_);return{oaa:j,delta:X}}async function co(T,_){if(_.length===0||!T.authz.oaa.isReady())return{status:"skipped"};return nn(T,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>T.authz.oaa.pushAccessChanges(_),{count:_.length})}async function nn(T,_,j,X,le){try{return await X(),{status:"ok"}}catch(ge){return T.log?.warn(j,{"ion.operation":_,"ion.outcome":"degraded",...le,error:Nt(ge)}),{status:"degraded",reason:Nt(ge)}}}var uo=6;async function lo(T,_){let j=T.iamDelta;if(!j?.isReady()||_.length===0)return{status:"skipped"};let X=new Map;for(let he of _){let me=`${he.change.subjectType}:${n(he.change.subject)}\x00${he.change.targetType}:${n(he.change.target)}`;X.set(me,he)}let le=[...X.values()],ge=le.map(({op:he,change:me})=>()=>he==="add"?j.onGrant(me):j.onRevoke(me)),Se=(await po(ge,uo)).filter((he)=>he.status==="rejected");if(Se.length>0)return T.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:Se.length,total:le.length,error:Nt(Se[0]?.reason)}),{status:"degraded",reason:Nt(Se[0]?.reason)};return{status:"ok"}}async function po(T,_){let j=Array(T.length),X=0,le=async()=>{while(!0){let ye=X++;if(ye>=T.length)return;let Se=T[ye];if(!Se)continue;try{j[ye]={status:"fulfilled",value:await Se()}}catch(he){j[ye]={status:"rejected",reason:he}}}},ge=Array.from({length:Math.min(_,T.length)},le);return await Promise.all(ge),j}class Fn extends Error{constructor(T){super(T);this.name="DerivedRevokeError",Object.setPrototypeOf(this,Fn.prototype)}}class Sn extends Error{constructor(T,_,j=!1){super(T);this.name="ScimMutationError",this.summary=_,this.clientError=j,Object.setPrototypeOf(this,Sn.prototype)}}function Ke(T,_,j){return new Response(JSON.stringify({schemas:[$r],status:String(T),scimType:j,detail:_}),{status:T,headers:w})}function Kt(T,_){let j=_?.totalResults??T.length,X=_?.startIndex??1,le=_?.itemsPerPage??T.length;return new Response(JSON.stringify({schemas:[no],totalResults:j,startIndex:X,itemsPerPage:le,Resources:T}),{status:200,headers:w})}function St(T,_=200,j){let X=new Headers(w);if(j)X.set("Location",j);return new Response(JSON.stringify(T),{status:_,headers:X})}function bs(T){return Ke(T.clientError?409:500,`${T.message}; authz mutation summary: ${JSON.stringify(T.summary)}`,T.clientError?"mutability":"invalidValue")}function Dn(T){return p(T)}function _r(T,_){return Hn(Cs(T),Cs(_))}function Cs(T){let _=new Map;if(!T?.id)return _;for(let j of T.groups??[]){let X={subject:T.id,subjectType:"user",targetType:"group",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type}:void 0};_.set(Dn(X),X)}for(let j of T.roles??[]){let X={subject:T.id,subjectType:"user",targetType:"role",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}for(let j of T.entitlements??[]){let X={subject:T.id,subjectType:"user",targetType:"permission",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}return _}class Yn extends Error{constructor(T){super(T);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,Yn.prototype)}}function mo(T,_,j){if(T.type==="Group")return;if(T.type==="Workload")return"workload";if(T.type==="User")return"user";if(T.type==="Customer")return"customer";let X=_??[];if(X.length===1)return X[0];throw new Yn(`SCIM Group member "${T.value}" of entitlement "${j}" omits type, and the entitlement is assignable to more than one principal kind [${X.join(", ")||"none"}]. Set members[].type to User, Workload, or Customer.`)}function Gn(T,_,j,X,le){let ge=new Map,ye=X&&X.length>0?X:void 0;for(let Se of T??[]){let he=mo(Se,le,j);if(!he)continue;let me={subject:Se.value,subjectType:he,targetType:_,target:j,resources:ye,metadata:Se.display||Se.type?{display:Se.display,type:Se.type}:void 0};ge.set(Dn(me),me)}return ge}function vs(T){let _=T[e]?.resources;return _&&_.length>0?_:void 0}function fo(T,_){let j=(le,ge)=>[...le??[]].sort().join(",")===[...ge??[]].sort().join(","),X=T[e];if(X?.type!==void 0&&X.type!==_.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==_.entity.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,qr(_.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,_.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,_.entity.recommendedSubjectTypes))return!0;return!1}function go(T,_){let j=(ge,ye)=>[...ge??[]].sort().join(",")===[...ye??[]].sort().join(","),X=T[e],le=_[e];if(X?.type!==void 0&&X.type!==le?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==le?.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,le?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,le?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,le?.recommendedSubjectTypes))return!0;return!1}function yo(T){let _=new Map;for(let j of T)_.set(Dn(j),j);return _}async function cn(T,_,j,X,le,ge){let ye=[],Se=new Set,he=(ze,Je)=>`${Je}\x00${ze}`,me=ge?ge.get(`${j}:${X}`)??[]:_?(await _.listByTarget(j,X)).items:[];for(let ze of me){let Je=n(ze.subject),Qe=ze.metadata,ut=ze.subjectType==="workload"?"Workload":ze.subjectType==="customer"?"Customer":Qe?.type??"User",st=he(Je,ut);if(Se.has(st))continue;Se.add(st),ye.push({value:Je,...Qe?.display?{display:Qe.display}:{},type:ut})}for(let ze of le??[]){if(ze.targetType!==j||n(ze.target)!==X)continue;let Je=n(ze.subject),Qe=he(Je,"Workload");if(Se.has(Qe))continue;Se.add(Qe),ye.push({value:Je,type:"Workload"})}if(j==="group"){let ze=await T.groups.get(X);for(let Je of ze?.groups??[]){let Qe=n(Je),ut=he(Qe,"Group");if(!Qe||Se.has(ut))continue;Se.add(ut),ye.push({value:Qe,type:"Group"})}}return ye.length>0?ye:void 0}function Hn(T,_){let j=[];for(let[X,le]of _)if(!T.has(X))j.push({action:"grant",change:le});for(let[X,le]of T)if(!_.has(X))j.push({action:"revoke",change:le});return j}async function jr(T,_){if(T.oaa.isReady())await T.oaa.pushUser(_)}async function Rs(T,_,j){if(_?.externalId&&_.externalId!==j.externalId)await T?.onUserDelete(_.externalId);await T?.onUserUpsert(j)}async function hn(T,_,j,X){let le={metadataApplied:!1,access:[]},ge={status:"skipped"},ye=[],Se=new Q(T.catalogStore,T.resources,T.codeCatalog);try{try{await _(),le.metadataApplied=!0}catch(he){for(let me of j)le.access.push({change:me.change,status:"rolled_back"});throw le.metadataApplied=!1,new Sn(`SCIM metadata write failed: ${Nt(he)}`,le,!1)}if(X?.oaa)await nn(T,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&T.iamDelta?.isReady())ge=await nn(T,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let he=0;he<j.length;he++){let me=j[he];try{if(me.action==="grant")await ao(T,me.change,ye,Se);else await bo(T,me.change,ye);le.access.push({change:me.change,status:"applied"})}catch(ze){le.access.push({change:me.change,status:"failed",error:ze});for(let Qe=he+1;Qe<j.length;Qe++)le.access.push({change:j[Qe].change,status:"rolled_back"});let Je=ze instanceof Fn||ze instanceof On;if(!Je)await So(T,me.change,Se);throw new Sn(Je?Nt(ze):`SCIM access mutation failed: ${Nt(ze)}`,le,Je)}}return le}finally{await ko(T),le.egress=await Jn(T,ye),le.egress.delta=ho(ge,le.egress.delta),wo(T,le)}}function ho(T,_){if(T.status==="degraded")return T;if(_.status==="degraded")return _;return T.status==="ok"||_.status==="ok"?{status:"ok"}:{status:"skipped"}}function Nt(T){return T instanceof Error?T.message:String(T)}async function ko(T){try{await T.settleAuthz?.()}catch{}}async function So(T,_,j){if(!T.accessIndex||!T.catalogStore&&!T.codeCatalog||!T.accessStore)return;let X=n(_.subject);if(!X)return;let le=_.subjectType;try{await pe(X,le,{accessStore:T.accessStore,accessIndex:T.accessIndex,catalogStore:T.catalogStore,code:T.codeCatalog,resources:T.resources},j)}catch(ge){T.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:le,error:Nt(ge)})}}function wo(T,_){if(!T.onAccessMutation)return;try{T.onAccessMutation(_)}catch{}}async function bo(T,_,j){if(T.accessStore){let X=_.id??p(_);if(!await T.accessStore.get(X)){if((T.accessIndex?await T.accessIndex.has(_.subject,_.targetType,_.target,_.resources?.[0],_.subjectType):{allow:!1}).allow)throw new Fn(`Cannot revoke ${_.targetType} "${n(_.target)}" for "${n(_.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await En(T,_,j);return}}await En(T,_,j)}function kn(T){let _=T[e]?.type??"group";if(_==="group"||_==="role"||_==="permission")return _;throw Error(`Unsupported ionite SCIM Group authz type "${String(_)}"`)}async function Lr(T,_,j){if(!T.oaa.isReady())return;if(j==="role"){await T.oaa.pushRole(_);return}if(j==="permission"){await T.oaa.pushPermission(_);return}await T.oaa.pushGroup(_)}function qr(T){let _=T.resources;if(!_||_.length===0)return;let j=_.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return j.length>0?j:void 0}function un(T,_,j){return Er(T,_,j)}function Co(T,_){let j=T[e],le={...o(j?.attributes??{},d),id:_,name:T.displayName,displayName:T.displayName,description:j?.description??T.displayName,requestable:j?.requestable,riskLevel:j?.riskLevel??f,providerId:j?.providerId??T.externalId,requestUrl:j?.requestUrl,assignableSubjectTypes:["user"]};if(j?.resources!==void 0)le.resources=j.resources;return le}function vo(T){if(!T)return;let _=T.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!_)return;return{requestable:_[1]?.toLowerCase()==="true"}}function As(T){if(!T)return;let _=T.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return _?_[1]:void 0}function Ro(T){if(!T)return;let _=T.trim(),j=_.match(/^userName\s+eq\s+"([^"]*)"$/i);if(j)return{userName:j[1]};let X=_.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(X)return{externalId:X[1]};let le=_.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(le)return{updatedAfter:le[1]};return}function Ao(T,_,j){let X=new Set(["id","schemas"]),le={...T};if(_){let ge=new Set(_.split(",").map((ye)=>ye.trim()).filter(Boolean));for(let ye of Object.keys(le))if(!X.has(ye)&&!ge.has(ye))delete le[ye]}if(j){for(let ge of j.split(",").map((ye)=>ye.trim()).filter(Boolean))if(!X.has(ge))delete le[ge]}return le}function Is(T,_){let j=async(ge,ye,Se)=>{let he=await T.toScim(ge),me=ge.id;return{...he,id:me,meta:{...he.meta??{},resourceType:T.resourceType,location:me?ht(ye,`${Se}/${encodeURIComponent(me)}`):void 0}}},X=(ge,ye)=>{let Se=ye.op.toLowerCase();if(!ye.path){if(Se!=="remove"&&ye.value&&typeof ye.value==="object"&&!Array.isArray(ye.value))Object.assign(ge,ye.value);return}if(Se==="remove"){delete ge[ye.path];return}ge[ye.path]=ye.value};return{handler:async(ge,ye)=>{if(!await _.validateAuth(ge))return Ke(401,"Authorization required");let Se=new URL(ge.url),he=ye?.basePath??`/${T.resourceType}s`,me=Se.pathname;if(me.startsWith(he))me=me.substring(he.length);let ze=me.match(/^\/([^/]+)$/),Je=ze?.[1]?decodeURIComponent(ze[1]):void 0,Qe=Se.searchParams.get("attributes"),ut=Se.searchParams.get("excludedAttributes"),st=(Ne)=>Ao(Ne,Qe,ut);try{if(Je){if(ge.method==="GET"){let Ne=await T.store.get(Je);if(!Ne)return Ke(404,`${T.resourceType} not found`);return St(st(await j(Ne,ge,he)))}if(ge.method==="PUT"||ge.method==="PATCH"){let Ne=await T.store.get(Je);if(!Ne)return Ke(404,`${T.resourceType} not found`);let Ve=await ge.json(),tt=Ve;if(ge.method==="PATCH"){let gt=Ve.Operations;if(!Array.isArray(gt))return Ke(400,"PATCH requires Operations","invalidSyntax");let Rt=await T.toScim(Ne);for(let Tt of gt)X(Rt,Tt);tt=Rt}let Oe=await tn(T.validator,tt);if(Oe.issues)return Ke(400,Oe.issues.map((gt)=>gt.message).join("; "),"invalidValue");let ct=ge.method==="PATCH"?"patch":"replace",ft=await T.store.upsert({...await T.fromScim(Oe.value,{existing:Ne,mode:ct}),id:Ne.id??Je});if(Ne.active!==ft.active)await _.accessIndex?.setSubjectDisabled?.(ft.id,T.subjectType,ft.active===!1);let bt=ft.id?ht(ge,`${he}/${encodeURIComponent(ft.id)}`):void 0;for(let gt of T.projections??[])await nn(_,`${gt.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM upsert; aggregation will reconcile`,()=>gt.upsert(ft,Ne));return St(st(await j(ft,ge,he)),200,bt)}if(ge.method==="DELETE"){let Ne=await T.store.get(Je);if(!Ne)return Ke(404,`${T.resourceType} not found`);if(_.revokeSubjectAccess)await _.revokeSubjectAccess(Je,T.subjectType);await T.store.delete(Je),await _.accessIndex?.setSubjectDisabled?.(Je,T.subjectType,!1);for(let Ve of T.projections??[])await nn(_,`${Ve.channel}.${T.subjectType}.delete`,`${T.resourceType} projection degraded after SCIM delete; aggregation will reconcile`,()=>Ve.delete(Ne));return new Response(null,{status:204})}return Ke(405,"Method not allowed")}if(ge.method==="GET"){let Ne=parseInt(Se.searchParams.get("startIndex")??"",10),Ve=parseInt(Se.searchParams.get("count")??"",10),tt=Ne!=null&&!Number.isNaN(Ne)?Math.max(0,Ne-1):0,Oe=Ve!=null&&!Number.isNaN(Ve)?Ve:void 0,ct=Ro(Se.searchParams.get("filter"));if(ct?.externalId!==void 0){let gt=T.store.getByExternalId?await T.store.getByExternalId(ct.externalId):await T.store.lookup({externalId:ct.externalId}),Rt=gt?[st(await j(gt,ge,he))]:[];return Kt(Rt,{totalResults:Rt.length,startIndex:1,itemsPerPage:Rt.length})}let ft=await T.store.list({start:tt,limit:Oe,filter:ct}),bt=await Promise.all(ft.items.map(async(gt)=>st(await j(gt,ge,he))));return Kt(bt,{totalResults:ft.total,startIndex:tt+1,itemsPerPage:ft.count})}if(ge.method==="POST"){let Ne=await ge.json(),Ve=await tn(T.validator,Ne);if(Ve.issues)return Ke(400,Ve.issues.map((ct)=>ct.message).join("; "),"invalidValue");let tt=await T.store.upsert(await T.fromScim(Ve.value,{mode:"create"}));if(tt.active===!1)await _.accessIndex?.setSubjectDisabled?.(tt.id,T.subjectType,!0);for(let ct of T.projections??[])await nn(_,`${ct.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM create; aggregation will reconcile`,()=>ct.upsert(tt,void 0));let Oe=tt.id?ht(ge,`${he}/${encodeURIComponent(tt.id)}`):void 0;return St(st(await j(tt,ge,he)),201,Oe)}return Ke(405,"Method not allowed")}catch(Ne){if(M(Ne))return Ke(409,Ne.message,"uniqueness");return Ke(500,Ne instanceof Error?Ne.message:"Internal error")}}}}async function Io(T,_,j,X){let le=[],ge=[["group",T.groups],["role",T.roles],["permission",T.permissions]];for(let[Se,he]of ge)for await(let me of c((ze,Je)=>he.list({start:ze,limit:Je,filter:{requestable:!0}})))if(me.providerId===j)le.push({entity:me,type:Se});if(le.length>1)throw new k(`Ambiguous providerId "${j}": ${le.length} entitlements share it (${le.map((Se)=>`${Se.type}:${Se.entity.id}`).join(", ")})`,"unique_violation","providerId");let ye=le[0];if(ye?.entity.requestable!==!0)return;return un(ye.entity,ye.type,await cn(T,_,ye.type,ye.entity.id,X))}async function To(T,_,j,X){let le=Math.max(0,j.start),ge=j.limit!=null?le+j.limit:void 0,ye={start:0,limit:ge,filter:j.filter},[Se,he,me]=await Promise.all([T.groups.list(ye),T.roles.list(ye),T.permissions.list(ye)]),ze=[...Se.items.map((Ne)=>({entity:Ne,type:"group"})),...he.items.map((Ne)=>({entity:Ne,type:"role"})),...me.items.map((Ne)=>({entity:Ne,type:"permission"}))],Je=Se.total+he.total+me.total,Qe=ze.slice(le,ge),ut=_?.listByTargets?await _.listByTargets(Qe.map(({entity:Ne,type:Ve})=>({targetType:Ve,target:Ne.id}))):void 0,st=await Promise.all(Qe.map(async({entity:Ne,type:Ve})=>un(Ne,Ve,await cn(T,_,Ve,Ne.id,X,ut))));return{resources:st,total:Je,count:st.length}}async function Un(T,_,j,X){let[le,ge,ye]=await Promise.all([T.groups.get(j),T.roles.get(j),T.permissions.get(j)]);if(le)return un(le,"group",await cn(T,_,"group",j,X));if(ge)return un(ge,"role",await cn(T,_,"role",j,X));if(ye)return un(ye,"permission",await cn(T,_,"permission",j,X));return}async function Nr(T,_,j,X,le){let ge=kn(_),ye=ge==="role"?await T.roles.get(j):ge==="permission"?await T.permissions.get(j):await T.groups.get(j),Se=Co(_,j),he=ye?.assignableSubjectTypes&&ye.assignableSubjectTypes.length>0?ye.assignableSubjectTypes:["user"],me={...ye??{},...Se,source:ye?.source??"scim",assignableSubjectTypes:le?.assignableSubjectTypes??he,recommendedSubjectTypes:le?.recommendedSubjectTypes??ye?.recommendedSubjectTypes};if(le){if(delete me.groups,delete me.roles,delete me.permissions,delete me.resources,ge==="group")me.groups=le.groups,me.roles=le.roles,me.permissions=le.permissions,me.resources=le.resources;else if(ge==="role")me.permissions=le.permissions}let ze=X?X.displayName??X.name:ye?.name;if(Se.displayName===ze)delete me.displayName;if(Se.riskLevel===(X?.riskLevel??f))delete me.riskLevel;let Je=o(Se,d),Qe=X?o(X,d):void 0;if(_[e]?.attributes!==void 0){for(let st of Object.keys(o(ye??{},d)??{}))if(!(st in(Je??{})))delete me[st]}for(let[st,Ne]of Object.entries(Je??{}))if(S(Ne,Qe?.[st]))delete me[st];if(X)me.name=X.name;let ut=ge==="role"?T.roles.set(me):ge==="permission"?T.permissions.set(me):T.groups.set(me);return await ut.ready(),ut}async function xo(T,_){await Promise.all([T.groups.delete(_),T.roles.delete(_),T.permissions.delete(_)])}function Kn(){return crypto.randomUUID()}function tn(T,_){let j=T;if(typeof j.validate==="function")return j.validate(_);return Promise.resolve(T["~standard"].validate(_))}function Po(T){if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}}function Lt(T){let _=Po(T);return _?R(_):void 0}function Ts(...T){for(let _ of T){let j=Lt(_);if(!j)continue;for(let X of["/Users","/Groups","/Workloads","/Customers"])if(j.endsWith(X))return j.slice(0,-X.length)}return}function ht(T,_){return new URL(_,T.url).toString()}function De(T,_,j,X){let{multiValued:le=!1,...ge}=X??{};return{name:T,type:_,description:j,multiValued:le,...ge}}function Uo(T,_){return{schemas:[ro],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:ht(T.request,`${T.basePath}/ServiceProviderConfig`)}}}function Eo(T){let _=[];if(T.supportsUsers)_.push({schemas:[Bn],id:"User",name:"User",description:"User Account",endpoint:T.usersUrl,schema:Wr,schemaExtensions:[{schema:Mn,required:!1},{schema:u,required:!1}],meta:{resourceType:"ResourceType",location:ht(T.request,`${T.basePath}/ResourceTypes/User`)}});if(T.supportsGroups)_.push({schemas:[Bn],id:"Group",name:"Group",description:"Group",endpoint:T.groupsUrl,schema:Vr,schemaExtensions:[{schema:e,required:!1}],meta:{resourceType:"ResourceType",location:ht(T.request,`${T.basePath}/ResourceTypes/Group`)}});if(T.supportsWorkloads)_.push({schemas:[Bn],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:T.workloadsUrl,schema:b,meta:{resourceType:"ResourceType",location:ht(T.request,`${T.basePath}/ResourceTypes/Workload`)}});if(T.supportsCustomers)_.push({schemas:[Bn],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:T.customersUrl,schema:C,meta:{resourceType:"ResourceType",location:ht(T.request,`${T.basePath}/ResourceTypes/Customer`)}});return _}function Do(T){let _=[];if(T.supportsUsers)_.push({schemas:[an],id:Wr,name:"User",description:"User Account",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Wr)}`)},attributes:[De("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),De("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),De("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),De("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[De("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),De("familyName","string","The family name of the User.",{multiValued:!1}),De("givenName","string","The given name of the User.",{multiValued:!1}),De("middleName","string","The middle name(s) of the User.",{multiValued:!1}),De("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),De("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),De("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),De("nickName","string","The casual way to address the user.",{multiValued:!1}),De("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),De("title","string","The user title, such as Vice President.",{multiValued:!1}),De("userType","string","The relationship between the organization and the User.",{multiValued:!1}),De("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),De("locale","string","Default location for localizing values.",{multiValued:!1}),De("timezone","string","The User time zone.",{multiValued:!1}),De("active","boolean","The User administrative status.",{multiValued:!1}),De("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[De("value","string","Email address value.",{multiValued:!1,required:!0}),De("display","string","Display label for the email.",{multiValued:!1}),De("type","string","Email type such as work or home.",{multiValued:!1}),De("primary","boolean","Primary email indicator.",{multiValued:!1})]}),De("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[De("value","string","Phone number value.",{multiValued:!1,required:!0}),De("display","string","Display label for the phone number.",{multiValued:!1}),De("type","string","Phone number type.",{multiValued:!1}),De("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),De("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[De("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),De("display","string","Display label for the photo.",{multiValued:!1}),De("type","string","Photo type.",{multiValued:!1}),De("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),De("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[De("formatted","string","Formatted mailing address.",{multiValued:!1}),De("streetAddress","string","Full street address component.",{multiValued:!1}),De("locality","string","City or locality.",{multiValued:!1}),De("region","string","State or region.",{multiValued:!1}),De("postalCode","string","Postal code.",{multiValued:!1}),De("country","string","Country.",{multiValued:!1}),De("type","string","Address type.",{multiValued:!1}),De("primary","boolean","Primary address indicator.",{multiValued:!1})]}),De("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[De("value","string","Group identifier.",{multiValued:!1,required:!0}),De("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),De("display","string","Display name of the group.",{multiValued:!1}),De("type","string","Relationship type.",{multiValued:!1})]}),De("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[De("value","string","Entitlement value.",{multiValued:!1,required:!0}),De("display","string","Display value.",{multiValued:!1}),De("type","string","Entitlement type.",{multiValued:!1}),De("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),De("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[De("value","string","Role value.",{multiValued:!1,required:!0}),De("display","string","Display value.",{multiValued:!1}),De("type","string","Role type.",{multiValued:!1}),De("primary","boolean","Primary role indicator.",{multiValued:!1})]}),De("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[De("value","string","Certificate value.",{multiValued:!1,required:!0}),De("display","string","Display value.",{multiValued:!1}),De("type","string","Certificate type.",{multiValued:!1}),De("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),_.push({schemas:[an],id:Mn,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Mn)}`)},attributes:[De("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),De("costCenter","string","Name of a cost center.",{multiValued:!1}),De("organization","string","Name of an organization.",{multiValued:!1}),De("division","string","Name of a division.",{multiValued:!1}),De("department","string","Name of a department.",{multiValued:!1}),De("manager","complex","The User manager.",{multiValued:!1,subAttributes:[De("value","string","Identifier of the manager User resource.",{multiValued:!1}),De("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),De("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),_.push({schemas:[an],id:u,name:"IoniteUser",description:"ionite User extension carrying ECID, account purpose, and AppDev custom attributes. See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(u)}`)},attributes:[De("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}),De("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1}),De("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[an],id:e,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(e)}`)},attributes:[De("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),De("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),De("riskLevel","string",`Advisory access-risk classification. Unset values project as ${f}; canonical values are suggestions, not a closed enum.`,{multiValued:!1,required:!1,mutability:"readWrite",canonicalValues:[...Y]}),De("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),De("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),De("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),De("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),De("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),De("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),De("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"]}),De("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"]}),De("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[an],id:Vr,name:"Group",description:"Group",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Vr)}`)},attributes:[De("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),De("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),De("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),De("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[De("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),De("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),De("display","string","Display name of the member.",{multiValued:!1}),De("type","string","Member type.",{multiValued:!1})]})]});if(T.supportsWorkloads)_.push({schemas:[an],id:b,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(b)}`)},attributes:[De("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),De("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),De("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),De("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),De("description","string","Free-form description of the Workload.",{multiValued:!1}),De("active","boolean","Administrative status of the Workload.",{multiValued:!1}),De("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsCustomers)_.push({schemas:[an],id:C,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:ht(T.request,`${T.basePath}/Schemas/${encodeURIComponent(C)}`)},attributes:[De("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),De("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),De("userName","string","Unique identifier typically used for login.",{multiValued:!1}),De("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),De("active","boolean","Administrative status of the Customer.",{multiValued:!1}),De("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[De("value","string","Email address.",{multiValued:!1,required:!0}),De("primary","boolean","Whether this is the primary email.",{multiValued:!1})]}),De("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});return _}function Mo(T,_,j,X,le,ge,ye,Se,he,me,ze,Je,Qe,ut,st,Ne){let Ve={authz:X,settleAuthz:Ne,accessStore:le,accessIndex:ge,catalogStore:ye,codeCatalog:Se,resources:he,log:_,iamDelta:Je,onAccessMutation:Qe,onInboundEntitlement:ut};if(!me&&!ze)return;let Oe={...me,...ze},ct=Oe.users?.enabled!==!1,ft=Oe.groups?.enabled!==!1,bt=Oe.workloads?.enabled!==!1,gt=Oe.customers?.enabled!==!1;if(Boolean(Oe.url||Oe.userStore||ye||Se)&&!j)_.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function Tt(){if(!j)throw _.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return j}async function Ot(Be){let Xe=Tt(),Ge=Be.headers.get("Authorization");if(!Ge?.startsWith("Bearer "))return!1;try{let Ze=Ge.substring(7);return(await Xe.validateToken(Ze)).valid}catch{return!1}}async function wn(){let Be=Tt(),Xe=typeof Be.getServerToken==="function"?await Be.getServerToken():await Be.getToken();return new Headers({...w,...ae,Authorization:`Bearer ${Xe}`})}async function Jt(Be,Xe,Ge,Ze){if(!Oe.url)throw Error("IAM URL not configured for outgoing requests");let He=`${Oe.url}${Xe}`;try{let Ye=await wn(),dt=await fetch(He,{method:Be,headers:Ye,body:Ge?JSON.stringify(Ge):void 0}),be=await a(dt,{log:_,operation:"scim.request"});if(!dt.ok)return{success:!1,error:be,status:dt.status};let Pe=await Ze["~standard"].validate(be);if(Pe.issues)return _.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:Pe.issues}),{success:!1,error:{schemas:[$r],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${Pe.issues.map((_e)=>_e.message).join("; ")}`},status:400};return{success:!0,data:Pe.value,status:dt.status}}catch(Ye){return{success:!1,error:{schemas:[$r],status:"500",detail:Ye instanceof Error?Ye.message:"Unknown error occurred"},status:500}}}function bn(){return Oe.url}function dn(Be,Xe){let Ge=Lt(Xe?.usersUrl??Oe.usersUrl??"/api/iam/Users")??"/api/iam/Users",Ze=Lt(Xe?.groupsUrl??Oe.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",He=Lt(Xe?.workloadsUrl??Oe.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",Ye=Lt(Xe?.customersUrl??Oe.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",dt=Lt(Xe?.discovery?.basePath??Oe.discovery?.basePath)??Ts(Ge,Ze,He,Ye);if(!dt)return;return{request:Be,basePath:dt,usersUrl:Ge,groupsUrl:Ze,workloadsUrl:He,customersUrl:Ye,supportsUsers:ct&&Boolean(Oe.userStore),supportsGroups:ft&&Boolean(ye||Se),supportsWorkloads:bt&&Boolean(Oe.workloadIdentityStore),supportsCustomers:gt&&Boolean(Oe.customerStore)}}async function Ht(Be){let Xe=Uo(Be,Oe.discovery);return await Oe.discovery?.buildServiceProviderConfig?.(Be,Xe)??Xe}async function Ft(Be){let Xe=Eo(Be);return await Oe.discovery?.buildResourceTypes?.(Be,Xe)??Xe}async function rn(Be){let Xe=Do(Be);return await Oe.discovery?.buildSchemas?.(Be,Xe)??Xe}async function ln(Be,Xe){let Ge=dn(Be,Xe);if(!Ge)return;let Ze=R(new URL(Be.url).pathname),{basePath:He}=Ge;if(Ze!==He&&!Ze.startsWith(`${He}/`))return;let Ye=R(Ze.slice(He.length)||"/");if(!(Ye==="/ServiceProviderConfig"||Ye==="/ResourceTypes"||Ye.startsWith("/ResourceTypes/")||Ye==="/Schemas"||Ye.startsWith("/Schemas/")))return;if(Be.method!=="GET")return Ke(405,"Method not allowed");if(!await Ot(Be))return Ke(401,"Authorization required");if(Ye==="/ServiceProviderConfig")return St(await Ht(Ge));if(Ye==="/ResourceTypes")return Kt(await Ft(Ge));if(Ye.startsWith("/ResourceTypes/")){let Pe=decodeURIComponent(Ye.slice(15)),_e=(await Ft(Ge)).find((fe)=>fe.id===Pe||fe.name===Pe);return _e?St(_e):Ke(404,"Resource not found")}if(Ye==="/Schemas")return Kt(await rn(Ge));if(Ye.startsWith("/Schemas/")){let Pe=decodeURIComponent(Ye.slice(9)),_e=(await rn(Ge)).find((fe)=>fe.id===Pe);return _e?St(_e):Ke(404,"Resource not found")}return}let xt,pn;if(Oe.url)pn=async(Xe,Ge)=>{let Ze={...Xe,schemas:Xe.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return Jt("POST","/Users",Ze,T.user)},xt={createGroup:async(Xe,Ge)=>{let Ze={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:Xe,externalId:Ge?.id,members:Ge?.members};return Jt("POST","/Groups",Ze,T.group)}};let Yt;if(ye||Se){let Be=q(Se,ye),Xe=(ve,ke,Ce)=>{let Ie=ve[e]??{},Re=kn(ve),Ee=ve.id,je=Ee?ht(ke,`${Ce}/${encodeURIComponent(Ee)}`):void 0,Ue={id:Ee??ve.externalId??ve.displayName,name:ve.displayName,displayName:ve.displayName,description:Ie.description??ve.displayName,requestable:Ie.requestable,providerId:Ie.providerId??ve.externalId,requestUrl:Ie.requestUrl,source:Ie.source,deprecated:Ie.deprecated,riskLevel:Ie.riskLevel,assignableSubjectTypes:Ie.assignableSubjectTypes,recommendedSubjectTypes:Ie.recommendedSubjectTypes},Le=Ie.requestUrl??Oe.entitlementRequestUrl?.(Ue,Re,{request:ke});return{...ve,meta:{...ve.meta,resourceType:"Group",location:je},[e]:{...Ie,requestUrl:Le}}},Ge=(ve)=>N(Se,ve),Ze=async(ve,ke)=>{if(!ye){if(ke)throw Error(`Cannot persist access for code entitlement "${ve.entity.id}": no AccessCatalogStore is wired.`);return ve.entity}try{return await K(ve.kind,ve.entity,L(ye,ve.kind))}catch(Ce){if(ke)throw Ce;return _.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:ve.entity.id,entitlementType:ve.kind,error:Nt(Ce)}),ve.entity}},He=async(ve)=>{if(!ye)return;try{await Z(Se,ye,ve)}catch(ke){_.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:ve,error:Nt(ke)})}},Ye=(ve,ke)=>Ke(403,`Entitlement "${ve}" is declared in application code; its structural definition cannot be ${ke} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),dt=(ve)=>ve.path==="members"||Boolean(ve.path?.startsWith("members[")),be=(ve)=>dt(ve)||ve.path==="displayName"||ve.path===`${e}.description`||ve.path===`${e}.riskLevel`||ve.path===`${e}.providerId`||ve.path===`${e}.requestUrl`||ve.path===`${e}.attributes`||Boolean(ve.path?.startsWith(`${e}.attributes.`)),Pe=(ve)=>ve?.[e]?.requestable===!0,_e=(ve)=>Ke(404,`Requestable Group ${ve} not found`,"invalidValue"),fe=async(ve,ke)=>{if(!await Ot(ve))return Ke(401,"Authorization required");let Ie=new URL(ve.url),Re=ke?.basePath??"/Groups",Ee=Ie.pathname;if(Ee.startsWith(Re))Ee=Ee.substring(Re.length);let Ue=Ee.match(/^\/([^/]+)$/)?.[1],Le=ve.method;try{if(Ue)switch(Le){case"GET":return await Te(ve,Re,Ue);case"PUT":return await xe(ve,Re,Ue);case"PATCH":return await qe(ve,Re,Ue);case"DELETE":return await We(Ue);default:return Ke(405,"Method not allowed")}else if(Ee===""||Ee==="/")switch(Le){case"GET":return await we(ve,Re);case"POST":return await Ae(ve,Re);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(Fe){if(Fe instanceof Sn)return bs(Fe);if(Fe instanceof Yn)return Ke(400,Fe.message,"invalidValue");if(M(Fe))return Ke(409,Fe.message,"uniqueness");return _.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},Fe),Ke(500,Fe instanceof Error?Fe.message:"Internal server error")}},we=async(ve,ke)=>{let Ce=new URL(ve.url),Ie=Ce.searchParams.get("startIndex"),Re=Ce.searchParams.get("count"),Ee=Ie!=null?parseInt(Ie,10):void 0,je=Re!=null?parseInt(Re,10):void 0,Ue=Ee!=null&&!Number.isNaN(Ee)?Math.max(0,Ee-1):0,Le=je!=null&&!Number.isNaN(je)?je:void 0,Fe=Ce.searchParams.get("filter"),rt=As(Fe);if(rt!==void 0){await He();let et=await Io(Be,le,rt,st),mt=et?[Xe(et,ve,ke)]:[];return Kt(mt,{totalResults:mt.length,startIndex:1,itemsPerPage:mt.length})}if(vo(Fe)?.requestable===!1)return Kt([],{totalResults:0,startIndex:1,itemsPerPage:0});let pt={requestable:!0};if(Se)await Promise.all([...Se.groups.list().filter((et)=>et.requestable===!0).map((et)=>({entity:et,kind:"group"})),...Se.roles.list().filter((et)=>et.requestable===!0).map((et)=>({entity:et,kind:"role"})),...Se.permissions.list().filter((et)=>et.requestable===!0).map((et)=>({entity:et,kind:"permission"}))].map((et)=>Ze(et,!1)));await He();let it=await To(Be,le,{start:Ue,limit:Le,filter:pt},st);return Kt(it.resources.map((et)=>Xe(et,ve,ke)),{totalResults:it.total,startIndex:Ue+1,itemsPerPage:it.count})},Te=async(ve,ke,Ce)=>{let Ie=Ge(Ce);if(Ie&&Ie.entity.requestable!==!0)return _e(Ce);if(Ie)await Ze(Ie,!1);await He(Ce);let Re=await Un(Be,le,Ce,st);if(!Pe(Re))return _e(Ce);return St(Xe(Re,ve,ke))},Ae=async(ve,ke)=>{let Ce=await ve.json(),Ie=await tn(T.group,Ce);if(Ie.issues)return _.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:Ie.issues}),Ke(400,`Request validation failed: ${Ie.issues.map((Mt)=>Mt.message).join("; ")}`,"invalidValue");let Re=Ie.value;if(!Re.displayName)return Ke(400,"displayName is required","invalidValue");if(Re[e]?.requestable===!1)return Ke(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(Re[e]={...Re[e],requestable:!0},!Ve.onInboundEntitlement)return Ke(501,"IAM-sourced entitlement creation is not implemented: this application declares no authz.onInboundEntitlement callback.","invalidValue");if(!ye)return Ke(501,"Group creation is not supported: this application declares its catalog in code (authz.catalog) and wires no AccessCatalogStore for SCIM-authored definitions.","invalidValue");let je=kn(Re),Ue=Re[e],Le=await Ve.onInboundEntitlement({type:je,displayName:Re.displayName,description:Ue?.description,externalId:Re.externalId,riskLevel:Ue?.riskLevel,attributes:Ue?.attributes,resources:Ue?.resources,members:Re.members??[],request:ve});if(!Le.accept)return Ke(403,Le.reason??"The application rejected the IAM-sourced entitlement");if((je==="role"?[...Le.groups??[],...Le.roles??[],...Le.resources??[]]:je==="permission"?[...Le.groups??[],...Le.roles??[],...Le.permissions??[],...Le.resources??[]]:[]).length>0)throw Error(`onInboundEntitlement returned structure that is invalid for entitlement type "${je}".`);let rt=Le.assignableSubjectTypes??["user"];x({id:Le.id,assignableSubjectTypes:rt,recommendedSubjectTypes:Le.recommendedSubjectTypes});let at=async(Mt,vt)=>{await Promise.all((vt??[]).map(async(qt)=>{if(!(Mt==="group"?await Be.groups.get(qt):Mt==="role"?await Be.roles.get(qt):Mt==="permission"?await Be.permissions.get(qt):await he?.get(qt)))throw Error(`onInboundEntitlement accepted "${Re.displayName}" with unknown ${Mt} binding "${qt}".`)}))};await Promise.all([at("group",Le.groups),at("role",Le.roles),at("permission",Le.permissions),at("resource",Le.resources)]);let pt=Le.id??Kn(),[it,et,mt]=await Promise.all([Be.groups.get(pt),Be.roles.get(pt),Be.permissions.get(pt)]);if(it||et||mt)throw new k(`id "${pt}" already exists in the entitlement catalog`,"unique_violation","id");let nt=Le.resources,Et=Hn(new Map,Gn(Re.members,je,pt,nt,rt)),Dt;await hn(Ve,async()=>{Dt=await Nr(Be,Re,pt,void 0,{...Le,assignableSubjectTypes:rt})},Et,{oaa:()=>Lr(X,Dt,je)});let Ct=await cn(Be,le,je,pt),Vt=Xe(un(Dt,je,Ct),ve,ke);return St(Vt,201,Vt.meta?.location)},xe=async(ve,ke,Ce)=>{let Ie=await ve.json(),Re=await tn(T.group,Ie);if(Re.issues)return _.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:Re.issues}),Ke(400,`Request validation failed: ${Re.issues.map((mt)=>mt.message).join("; ")}`,"invalidValue");let Ee=Re.value,je=kn(Ee),Ue=Ge(Ce);if(Ue&&Ue.entity.requestable!==!0)return _e(Ce);if(Ue){if(await Ze(Ue,!0),fo(Ee,Ue))return Ye(Ce,"replaced")}let Le=await Un(Be,le,Ce);if(!Pe(Le))return _e(Ce);if(!Ue&&Le[e]?.source==="code"&&go(Ee,Le))return Ye(Ce,"replaced");let Fe=Ue?.kind??je,rt=Ue?qr(Ue.entity):vs(Ee),at=le?(await le.listByTarget(Fe,Ce)).items:[],pt=Hn(yo(at),Gn(Ee.members,Fe,Ce,rt,Ue?.entity.assignableSubjectTypes??Le[e]?.assignableSubjectTypes??Ee[e]?.assignableSubjectTypes)),it;await hn(Ve,async()=>{it=await Nr(Be,Ee,Ce,Ue?.entity)},pt,{oaa:()=>Lr(X,it,Fe)});let et=await cn(Be,le,Fe,Ce);return St(Xe(un(it,Fe,et),ve,ke))},qe=async(ve,ke,Ce)=>{let Ie=Ge(Ce);if(Ie&&Ie.entity.requestable!==!0)return _e(Ce);if(Ie)await Ze(Ie,!0);let Re=await Un(Be,le,Ce);if(!Pe(Re))return _e(Ce);let Ee=await ve.json();if((Ie!==void 0||Re[e]?.source==="code")&&(Ee.Operations??[]).some((nt)=>!be(nt)))return Ye(Ce,"patched");let Ue={...Re};for(let nt of Ee.Operations??[])if(nt.op==="replace"&&nt.path&&nt.value!==void 0){if(nt.path==="displayName")Ue.displayName=nt.value;else if(nt.path===`${e}.requestable`)Ue[e]={...Ue[e],requestable:Boolean(nt.value)};else if(nt.path===`${e}.description`)Ue[e]={...Ue[e],description:String(nt.value)};else if(nt.path===`${e}.riskLevel`)Ue[e]={...Ue[e],riskLevel:String(nt.value)};else if(nt.path===`${e}.providerId`)Ue[e]={...Ue[e],providerId:String(nt.value)};else if(nt.path===`${e}.requestUrl`)Ue[e]={...Ue[e],requestUrl:String(nt.value)};else if(nt.path===`${e}.attributes`&&typeof nt.value==="object"&&nt.value!==null&&!Array.isArray(nt.value))Ue[e]={...Ue[e],attributes:nt.value};else if(nt.path.startsWith(`${e}.attributes.`)){let Et=nt.path.slice(`${e}.attributes.`.length);Ue[e]={...Ue[e],attributes:{...Ue[e]?.attributes,[Et]:nt.value}}}}else if(nt.op==="add"&&nt.path==="members"&&nt.value!==void 0){let Et=nt.value;Ue.members=[...Ue.members??[],...Et]}else if(nt.op==="remove"&&nt.path?.startsWith("members[")){let Et=nt.path.match(/members\[value eq "([^"]+)"\]/);if(Et)Ue.members=(Ue.members??[]).filter((Dt)=>Dt.value!==Et[1])}else if(nt.op==="remove"&&nt.path?.startsWith(`${e}.attributes.`)){let Et=nt.path.slice(`${e}.attributes.`.length),Dt={...Ue[e]?.attributes};delete Dt[Et],Ue[e]={...Ue[e],attributes:Dt}}let Le=await tn(T.group,Ue);if(Le.issues)return _.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:Le.issues}),Ke(400,`Request validation failed: ${Le.issues.map((nt)=>nt.message).join("; ")}`,"invalidValue");let Fe=Ie?.kind??kn(Ue),rt=Ie?qr(Ie.entity):vs(Ue),at=Ie?.entity.assignableSubjectTypes??Re[e]?.assignableSubjectTypes??Ue[e]?.assignableSubjectTypes,pt=Hn(Gn(Re.members,Fe,Ce,rt,at),Gn(Ue.members,Fe,Ce,rt,at)),it,et=!Ie||(Ee.Operations??[]).some((nt)=>!dt(nt));await hn(Ve,async()=>{if(et)it=await Nr(Be,Ue,Ce,Ie?.entity)},pt,et?{oaa:()=>Lr(X,it,Fe)}:void 0);let mt=await Un(Be,le,Ce);return St(Xe(mt,ve,ke))},We=async(ve)=>{let ke=Ge(ve);if(ke&&ke.entity.requestable!==!0)return _e(ve);if(ke)await Ze(ke,!0);let Ce=await Un(Be,le,ve);if(!Pe(Ce))return _e(ve);let Ie=Ce[e];if((ke||Ie?.source==="code")&&Ie?.deprecated!==!0)return Ke(403,`Code-owned entitlement "${ve}" can be deleted only after it is marked deprecated.`,"mutability");let Re=kn(Ce);if(le){let Ee=await le.listByTarget(Re,ve),je=[];for(let Ue of Ee.items)await En(Ve,Ue,je);await Jn(Ve,je)}return await xo(Be,ve),new Response(null,{status:204})};Yt={handler:fe}}let Pt,At,$t;if(Oe.userStore){let{userStore:Be,inboundUsers:Xe}=Oe,Ge=(ke)=>ke?.find((Ce)=>Ce.primary)?.value||ke?.[0]?.value,Ze=async(ke)=>{if(Xe?.mapBaseUserToScim)return await Xe.mapBaseUserToScim(ke);return Dr(ke)},He=async(ke,Ce,Ie)=>{let Re=await Ze(ke),Ee=Re.id??ke.id;return{...Re,id:Ee,meta:{...Re.meta,resourceType:"User",location:Ee?ht(Ce,`${Ie}/${encodeURIComponent(Ee)}`):void 0}}},Ye=async(ke,Ce)=>{if(Xe?.mapValidatedScimToBaseUser)return await Xe.mapValidatedScimToBaseUser(ke,Ce);let Ie=new Date,Re=Ge(ke.emails),Ee=ke.name?.formatted||[ke.name?.givenName,ke.name?.middleName,ke.name?.familyName].filter(Boolean).join(" ").trim()||ke.displayName,je=ke.id||Ce.existing?.id||Kn(),Ue=ke.userName||Re||Ce.existing?.userName||je,Le=Ee||ke.displayName||Ce.existing?.name||Ue,Fe=Object.fromEntries(Object.entries(ke).filter(([mt,nt])=>mt.startsWith("urn:")&&mt!==Mn&&mt!==u&&nt!==void 0)),rt=ke[u],at=o(rt?.attributes??{},A),pt=rt?.ecid!==void 0&&rt.ecid!==null?O(rt.ecid):Ce.existing?.ecid,it=rt?.accountClass??Ce.existing?.accountClass,et=Ce.existing?.sso;return{...Ce.existing??{},id:je,userName:Ue,name:Le,email:Re||Ce.existing?.email||Ue,avatar:ke.profileUrl,sso:{...et??{},profile:{...et?.profile??{},sub:je,iss:et?.profile.iss??"iam-provisioned",aud:et?.profile.aud??"iam-provisioned",exp:et?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:et?.profile.iat??Math.floor(Date.now()/1000),email:Re||Ce.existing?.email||Ue,email_verified:!0,name:Le,preferred_username:Ue},tenant:et?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:et?.scope??"openid profile email",tokenType:et?.tokenType??"Bearer",expires:et?.expires??new Date(Date.now()+3600000)},externalId:ke.externalId,ecid:pt,accountClass:it,displayName:ke.displayName,scimName:ke.name,emails:ke.emails,nickName:ke.nickName,title:ke.title,preferredLanguage:ke.preferredLanguage,locale:ke.locale,timezone:ke.timezone,active:ke.active,phoneNumbers:ke.phoneNumbers,ims:ke.ims,photos:ke.photos,addresses:ke.addresses,groups:ke.groups,entitlements:ke.entitlements,roles:ke.roles,x509Certificates:ke.x509Certificates,scimEnterprise:ke[Mn],scimSchemaExtensions:Object.keys(Fe).length>0?Fe:void 0,createdAt:Ce.existing?.createdAt??(ke.meta?.created?new Date(ke.meta.created):Ie),updatedAt:ke.meta?.lastModified?new Date(ke.meta.lastModified):Ie,userType:ke.userType,...at}},dt=(ke,Ce,Ie)=>{ke[Ce]=Ie},be=(ke,Ce,Ie)=>{let Re=ke[Ce];if(Array.isArray(Re)){ke[Ce]=[...Re,...Array.isArray(Ie)?Ie:[Ie]];return}if(Re&&typeof Re==="object"&&!Array.isArray(Re)&&Ie&&typeof Ie==="object"&&!Array.isArray(Ie)){ke[Ce]={...Re,...Ie};return}ke[Ce]=Ie},Pe=(ke,Ce,Ie)=>{let Re=Ce.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),Ee=Re?[Re[1],...Re[2]?.split(":")??[]]:Ce.split("."),je=ke;for(let Le of Ee.slice(0,-1)){let Fe=je[Le];if(Fe===void 0){if(!Ie)return null;je[Le]={}}else if(Fe===null||typeof Fe!=="object"||Array.isArray(Fe)){if(!Ie)return null;je[Le]={}}je=je[Le]}let Ue=Ee.at(-1);if(!Ue)return null;return{parent:je,key:Ue}},_e=(ke,Ce)=>{let Ie=Ce.op.toLowerCase();if(!Ce.path){if(Ie!=="remove"&&Ce.value&&typeof Ce.value==="object"&&!Array.isArray(Ce.value))Object.assign(ke,Ce.value);return}let Re=Ce.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(Re&&Ie==="remove"){let[,je,Ue]=Re,Le=ke[je];if(Array.isArray(Le))ke[je]=Le.filter((Fe)=>!(Fe&&typeof Fe==="object"&&("value"in Fe)&&Fe.value===Ue));return}let Ee=Pe(ke,Ce.path,Ie!=="remove");if(!Ee)return;if(Ie==="remove"){delete Ee.parent[Ee.key];return}if(Ie==="add"){be(Ee.parent,Ee.key,Ce.value);return}dt(Ee.parent,Ee.key,Ce.value)},fe=async(ke,Ce)=>{if(!await Ot(ke))return Ke(401,"Authorization required");let Re=new URL(ke.url),Ee=Ce?.basePath??"/Users",je=Re.pathname;if(je.startsWith(Ee))je=je.substring(Ee.length);let Le=je.match(/^\/([^/]+)$/)?.[1],Fe=ke.method;try{if(Le)switch(Fe){case"GET":return await Te(ke,Ee,Le);case"PUT":return await qe(ke,Ee,Le);case"PATCH":return await We(ke,Ee,Le);case"DELETE":return await ve(Le);default:return Ke(405,"Method not allowed")}else if(je===""||je==="/")switch(Fe){case"GET":return await we(ke,Ee);case"POST":return await xe(ke,Ee);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(rt){if(rt instanceof Sn)return bs(rt);if(M(rt))return Ke(409,rt.message,"uniqueness");return _.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},rt),Ke(500,rt instanceof Error?rt.message:"Internal server error")}},we=async(ke,Ce)=>{let Ie=new URL(ke.url),Re=Ie.searchParams.get("startIndex"),Ee=Ie.searchParams.get("count"),je=Re!=null?parseInt(Re,10):void 0,Ue=Ee!=null?parseInt(Ee,10):void 0,Le=je!=null&&!Number.isNaN(je)?Math.max(0,je-1):0,Fe=Ue!=null&&!Number.isNaN(Ue)?Ue:void 0,rt=As(Ie.searchParams.get("filter"));if(rt!==void 0){let it=await Be.lookup({externalId:rt}),et=it?[await He(it,ke,Ce)]:[];return Kt(et,{totalResults:et.length,startIndex:1,itemsPerPage:et.length})}let at=await Be.list({start:Le,limit:Fe}),pt=await Promise.all(at.items.map((it)=>He(it,ke,Ce)));return Kt(pt,{totalResults:at.total,startIndex:Le+1,itemsPerPage:at.count})},Te=async(ke,Ce,Ie)=>{let Re=await Be.get(Ie);if(!Re)return Ke(404,`User ${Ie} not found`,"invalidValue");return St(await He(Re,ke,Ce))},Ae=async(ke,Ce)=>{let Ie=Ve.accessIndex;if(!Ie?.setSubjectDisabled||!Ce.id)return;let Re=ke?ke.active??!0:!0,Ee=Ce.active??!0;if(ke&&Re===Ee)return;if(!ke&&Ee)return;await Ie.setSubjectDisabled(Ce.id,"user",!Ee)},xe=async(ke,Ce)=>{let Ie=await ke.json(),Re=await tn(T.user,Ie);if(Re.issues)return _.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:Re.issues}),Ke(400,`Request validation failed: ${Re.issues.map((Le)=>Le.message).join("; ")}`,"invalidValue");let Ee=Re.value;if(!Ee.userName&&!Ee.emails?.[0]?.value)return Ke(400,"userName or email is required","invalidValue");let je=await Ye(Ee,{mode:"create"});await hn(Ve,async()=>{await Be.upsert(je),await Ae(void 0,je)},_r(void 0,je),{oaa:async()=>{await jr(X,je)},delta:async()=>{await Ve.iamDelta?.onUserUpsert(je)}});let Ue=await He(je,ke,Ce);return St(Ue,201,Ue.meta?.location)},qe=async(ke,Ce,Ie)=>{let Re=await Be.get(Ie);if(!Re)return Ke(404,`User ${Ie} not found`,"invalidValue");let Ee=await ke.json(),je=await tn(T.user,Ee);if(je.issues)return _.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:je.issues}),Ke(400,`Request validation failed: ${je.issues.map((Fe)=>Fe.message).join("; ")}`,"invalidValue");let Ue=je.value,Le=await Ye({...Ue,id:Ie},{existing:Re,mode:"replace"});return Le.createdAt=Re.createdAt,Le.updatedAt=new Date,await hn(Ve,async()=>{await Be.upsert(Le),await Ae(Re,Le)},_r(Re,Le),{oaa:async()=>{await jr(X,Le)},delta:async()=>{await Rs(Ve.iamDelta,Re,Le)}}),St(await He(Le,ke,Ce))},We=async(ke,Ce,Ie)=>{let Re=await Be.get(Ie);if(!Re)return Ke(404,`User ${Ie} not found`,"invalidValue");let je=(await ke.json()).Operations??[],Le={...await Ze(Re)};for(let at of je)_e(Le,at);let Fe=await tn(T.user,Le);if(Fe.issues)return _.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:Fe.issues}),Ke(400,`Request validation failed: ${Fe.issues.map((at)=>at.message).join("; ")}`,"invalidValue");let rt=await Ye(Fe.value,{existing:Re,mode:"patch"});return rt.updatedAt=new Date,await hn(Ve,async()=>{await Be.upsert(rt),await Ae(Re,rt)},_r(Re,rt),{oaa:async()=>{await jr(X,rt)},delta:async()=>{await Rs(Ve.iamDelta,Re,rt)}}),St(await He(rt,ke,Ce))},ve=async(ke)=>{let Ce=await Be.get(ke);if(!Ce)return Ke(404,`User ${ke} not found`,"invalidValue");if(le){let Ie=[];for await(let Re of c((Ee,je)=>le.listBySubject(ke,"user",{start:Ee,limit:je})))await En(Ve,Re,Ie);await Jn(Ve,Ie)}if(await Be.delete(ke),await Ve.accessIndex?.setSubjectDisabled?.(ke,"user",!1),Ce.externalId&&Ve.iamDelta?.isReady())await nn(Ve,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>Ve.iamDelta?.onUserDelete(Ce.externalId)??Promise.resolve(),{id:ke,kind:"user"});else if(Ve.iamDelta?.isReady())Ve.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:ke,kind:"user"});if(Ve.authz.oaa.isReady())await nn(Ve,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>Ve.authz.oaa.deleteUser(ke),{id:ke,kind:"user"});return new Response(null,{status:204})};Pt={handler:fe}}let Wt=async(Be,Xe)=>{if(!le)return;let Ge=[];for await(let Ze of c((He,Ye)=>le.listBySubject(Be,Xe,{start:He,limit:Ye})))await En(Ve,Ze,Ge);await Jn(Ve,Ge)};if(Oe.workloadIdentityStore){let{workloadIdentityStore:Be,inboundWorkloads:Xe}=Oe;At=Is({resourceType:"Workload",subjectType:"workload",store:Be,validator:T.workload??ue,toScim:async(Ge)=>await(Xe?.mapBaseWorkloadToScim?.(Ge)??Mr(Ge)),fromScim:async(Ge,Ze)=>{if(Xe?.mapValidatedScimToBaseWorkload)return Xe.mapValidatedScimToBaseWorkload(Ge,Ze);let He=Ze.existing,Ye=Ge,dt=Ye.id?.trim()||He?.id||Kn(),be=o(Ye.attributes??{},v);return{...He??{},id:dt,externalId:Ye.externalId??He?.externalId,clientId:Ye.userName??He?.clientId??dt,displayName:Ye.displayName??He?.displayName,description:Ye.description??He?.description,active:Ye.active??He?.active??!0,providerId:He?.providerId,requestUrl:He?.requestUrl,...be}},projections:[{channel:"oaa",upsert:async(Ge)=>{if(X.oaa.isReady())await X.oaa.pushWorkload(Ge)},delete:async(Ge)=>{if(X.oaa.isReady())await X.oaa.deleteWorkload(Ge.id)}},{channel:"delta",upsert:async(Ge,Ze)=>{let He=Ze?.externalId??Ze?.id,Ye=Ge.externalId??Ge.id;if(He&&He!==Ye)await Je?.onWorkloadDelete(He);await Je?.onWorkloadUpsert(Ge)},delete:async(Ge)=>{await Je?.onWorkloadDelete(Ge.externalId??Ge.id)}}]},{validateAuth:Ot,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}if(Oe.customerStore){let{customerStore:Be,inboundCustomers:Xe}=Oe;$t=Is({resourceType:"Customer",subjectType:"customer",store:Be,validator:T.customer??de,toScim:async(Ge)=>await(Xe?.mapBaseCustomerToScim?.(Ge)??Or(Ge)),fromScim:async(Ge,Ze)=>{if(Xe?.mapValidatedScimToBaseCustomer)return Xe.mapValidatedScimToBaseCustomer(Ge,Ze);let He=Ze.existing,Ye=Ge,dt=Ye.id?.trim()||He?.id||Kn(),be=o(Ye.attributes??{},I),Pe=Ye.emails?.find((_e)=>_e.primary)?.value??Ye.emails?.[0]?.value;return{...He??{},id:dt,externalId:Ye.externalId??He?.externalId??dt,userName:Ye.userName??He?.userName??dt,name:Ye.displayName??He?.name??Ye.userName??dt,email:Pe??He?.email??"",displayName:Ye.displayName??He?.displayName,emails:Ye.emails??He?.emails,active:Ye.active??He?.active??!0,providerId:He?.providerId,requestUrl:He?.requestUrl,...be}},projections:[{channel:"oaa",upsert:async(Ge)=>{if(X.oaa.isReady())await X.oaa.pushCustomer(Ge)},delete:async(Ge)=>{if(X.oaa.isReady()&&Ge.id)await X.oaa.deleteCustomer(Ge.id)}},{channel:"delta",upsert:async(Ge,Ze)=>{let He=Ze?.externalId??Ze?.id,Ye=Ge.externalId??Ge.id;if(He&&He!==Ye)await Je?.onCustomerDelete(He);await Je?.onCustomerUpsert(Ge)},delete:async(Ge)=>{let Ze=Ge.externalId??Ge.id;if(Ze)await Je?.onCustomerDelete(Ze)}}]},{validateAuth:Ot,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}async function Xt(Be,Xe){Tt();let Ge=new URL(Be.url).pathname,Ze=Lt(Xe?.usersUrl??Oe.usersUrl??"/api/iam/Users")??"/api/iam/Users",He=Lt(Xe?.groupsUrl??Oe.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Ye=Lt(Xe?.workloadsUrl??Oe.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",dt=Lt(Xe?.customersUrl??Oe.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",be=`${Ts(Ze,He,Ye,dt)??"/api/iam"}/AccessRequests`,Pe=await ln(Be,Xe);if(Pe)return Pe;let _e=(fe)=>Ge===fe||Ge.startsWith(`${fe}/`);if(_e(Ze)){if(!ct)return Ke(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!Pt)return Ke(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return Pt.handler(Be,{basePath:Ze})}if(_e(He)){if(!ft)return Ke(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!Yt)return Ke(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return Yt.handler(Be,{basePath:He})}if(_e(Ye)){if(!bt)return Ke(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!At)return Ke(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return At.handler(Be,{basePath:Ye})}if(_e(dt)){if(!gt)return Ke(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!$t)return Ke(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return $t.handler(Be,{basePath:dt})}if(_e(be)){if(!Oe.accessRequests)return Ke(404,"AccessRequests endpoint is not configured");if(!await Ot(Be))return Ke(401,"Authorization required");if(Be.method==="GET"){if(!Oe.accessRequests.get)return Ke(404,"AccessRequests read endpoint is not configured");let Te=Ge.startsWith(`${be}/`)?Ge.slice(be.length+1):void 0;if(!Te||Te.includes("/"))return Ke(404,"AccessRequest not found");let Ae;try{Ae=decodeURIComponent(Te)}catch{return Ke(400,"AccessRequest id is invalid","invalidValue")}let xe=await Oe.accessRequests.get(Ae);if(!xe)return Ke(404,"AccessRequest not found");return St(xe,200,xe.trackingUrl)}if(Be.method!=="POST"||Ge!==be)return Ke(405,"Method not allowed");let fe;try{fe=await Be.json()}catch{return Ke(400,"Request body must be valid JSON","invalidSyntax")}if(typeof fe.subject!=="string"||!fe.subject||typeof fe.target!=="string"||!fe.target||fe.subjectType!=="user"&&fe.subjectType!=="workload"&&fe.subjectType!=="customer"||fe.targetType!=="group"&&fe.targetType!=="role"&&fe.targetType!=="permission"||fe.operation!=="grant"&&fe.operation!=="revoke")return Ke(400,"subject, subjectType, targetType, target, and operation are required","invalidValue");let we=await Oe.accessRequests.create({subject:fe.subject,subjectType:fe.subjectType,targetType:fe.targetType,target:fe.target,operation:fe.operation,justification:typeof fe.justification==="string"?fe.justification:void 0});return St(we.request,we.created?201:200,we.request.trackingUrl)}return Ke(404,"Resource not found")}let Ut;return Ut={...Oe,describe:()=>({module:"iam",active:!0,ready:Ut.isReady?.()??!0,url:Oe.url,deltaAudience:Oe.deltaAudience,accessRequests:{...Oe.url?{iam:`${R(Oe.url)}/AccessRequests`}:{},ciam:{}},users:{...yn(Oe.users),storeWired:Oe.userStore!==void 0},workloads:{...yn(Oe.workloads),storeWired:Oe.workloadIdentityStore!==void 0},customers:{...yn(Oe.customers),storeWired:Oe.customerStore!==void 0},groups:{enabled:ft,catalogWired:ye!==void 0},urls:{usersUrl:Oe.usersUrl??"",groupsUrl:Oe.groupsUrl??"",workloadsUrl:Oe.workloadsUrl??"",customersUrl:Oe.customersUrl??""}}),users:yn(Oe.users),workloads:yn(Oe.workloads),customers:yn(Oe.customers),groups:{enabled:ft},createUser:pn,getBaseUrl:bn,groups_outbound:xt,groups_inbound:Yt,users_inbound:Pt,workloads_inbound:At,customers_inbound:$t,handler:Xt,delta:Je},Ut}function zr(T,_){let j=new TextEncoder().encode(T),X=typeof _==="string"?new TextEncoder().encode(_):_,le=new Uint8Array(j.length+1+X.length);return le.set(j,0),le[j.length]=46,le.set(X,j.length+1),le}function Oo(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.length%4===0?"":"=".repeat(4-_.length%4),X=atob(_+j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function _o(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Ps(T){let _=JSON.parse(T);if(!_||typeof _!=="object"||!Array.isArray(_.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return _}function jo(T){return JSON.stringify(T)}async function Lo(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x},{name:"Ed25519"},!0,["verify"])}async function No(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x,d:T.d},{name:"Ed25519"},!0,["sign"])}async function $o(T){let j=(typeof T.jwks==="string"?Ps(T.jwks):T.jwks).keys.find((X)=>X.kid===T.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!j?.x)return!1;try{let X=await Lo(j),le=zr(T.requestId,T.rawBody),ge=Oo(T.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,ge,le)}catch{return!1}}async function Wo(T){let _=await No(T.privateKeyJwk),j=zr(T.requestId,T.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},_,j);return _o(new Uint8Array(X))}async function Vo(T){let _=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),j=await crypto.subtle.exportKey("jwk",_.privateKey),le=(await crypto.subtle.exportKey("jwk",_.publicKey)).x,ge=j.d;if(!le||!ge)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:le,d:ge,kid:T,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:le,kid:T,alg:"EdDSA",use:"sig"}]}}}var _n={jwksTtlSeconds:{min:60,max:86400,default:600},jwksMaxEntries:{min:16,max:4096,default:256},sessionReadTtlSeconds:{min:1,max:300,default:30},sessionReadMaxEntries:{min:16,max:65536,default:1024}};function Xn(T,_){if(typeof T!=="number"||!Number.isFinite(T))return _.default;let j=Math.floor(T);if(j<_.min)return _.min;if(j>_.max)return _.max;return j}function Us(T){return{ttlMs:Xn(T?.ttlSeconds,_n.jwksTtlSeconds)*1000,maxEntries:Xn(T?.maxEntries,_n.jwksMaxEntries)}}function Es(T){let _=T?.read;return{read:{enabled:_?.enabled===!0,ttlMs:Xn(_?.ttlSeconds,_n.sessionReadTtlSeconds)*1000,maxEntries:Xn(_?.maxEntries,_n.sessionReadMaxEntries)}}}function qo(T){return{jwks:Us(T?.jwks),session:Es(T?.session)}}var Zn=new TextEncoder,zo=new TextDecoder;function Os(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Ds(T){return Os(Zn.encode(JSON.stringify(T)))}function _s(T){if(!/^[A-Za-z0-9_-]+$/.test(T))return;let _=T.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(T.length/4)*4,"=");try{return Uint8Array.from(atob(_),(j)=>j.charCodeAt(0))}catch{return}}function Ms(T){let _=_s(T);if(!_)return;try{let j=JSON.parse(zo.decode(_));return j!==null&&typeof j==="object"&&!Array.isArray(j)?j:void 0}catch{return}}function Bo(T){return Zn.encode(T)}function js(T){let _=new Uint8Array(T.byteLength);return _.set(T),_.buffer}async function Ls(T){return crypto.subtle.importKey("raw",js(Bo(T)),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function Go(T){let _=T.active.trim(),j=new Map(Object.entries(T.keys).map(([le,ge])=>[le.trim(),{kid:le.trim(),secret:ge}])),X=j.get(_);if(!_||!X?.secret)throw Error("Signing key ring must name a non-empty active key.");for(let le of j.values())if(!le.kid||!le.secret)throw Error("Signing key ring ids and secrets must be non-empty.");return{current:()=>X,find:(le)=>j.get(le)}}async function Ko(T,_,j){let X=Math.floor(j.ttlSeconds);if(!Number.isFinite(X)||X<1)throw Error("Compact JWT ttlSeconds must be a positive integer.");let le=_.current();if(!le.kid||!le.secret)throw Error("Signing key ring returned an invalid active key.");let ge=Math.floor(Date.now()/1000),ye=Ds({alg:"HS256",kid:le.kid,typ:"JWT"}),Se=Ds({...T,iat:ge,exp:ge+X}),he=`${ye}.${Se}`,me=await crypto.subtle.sign("HMAC",await Ls(le.secret),Zn.encode(he));return`${he}.${Os(new Uint8Array(me))}`}async function Jo(T,_){let j=T.split(".");if(j.length!==3)return null;let[X,le,ge]=j;if(!X||!le||!ge)return null;let ye=Ms(X);if(ye?.alg!=="HS256"||ye.typ!=="JWT"||typeof ye.kid!=="string")return null;let Se=_.find(ye.kid);if(!Se?.secret)return null;let he=_s(ge);if(!he)return null;if(!await crypto.subtle.verify("HMAC",await Ls(Se.secret),js(he),Zn.encode(`${X}.${le}`)))return null;let ze=Ms(le);if(!ze)return null;let{iat:Je,exp:Qe}=ze;if(typeof Je!=="number"||typeof Qe!=="number"||!Number.isSafeInteger(Je)||!Number.isSafeInteger(Qe))return null;let ut=Math.floor(Date.now()/1000);if(Je>ut+60||Qe+60<=ut)return null;return ze}function Ho(T){let _={};if(!T)return _;let j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;_[le.slice(0,ge).trim()]=le.slice(ge+1).trim()}return _}function Ns(T){if(!T.expiresAt)return!1;let _=T.expiresAt instanceof Date?T.expiresAt:new Date(T.expiresAt);return!Number.isNaN(_.getTime())&&Date.now()>_.getTime()}function Fo(T){if(!T||typeof T!=="object"||Array.isArray(T))return;let{access_token:_,id_token:j,refresh_token:X,tokens:le,...ge}=T;return ge}function jt(T,_){let j=T[_];return typeof j==="string"?j:""}function Yo(T,_){let j=T.exp;if(typeof j==="number")return new Date(j*1000);if(typeof j==="string"&&j.trim()){let X=Number(j);if(!Number.isNaN(X))return new Date(X*1000)}if(_ instanceof Date)return _;if(_){let X=new Date(_);if(!Number.isNaN(X.getTime()))return X}return new Date}function Xo(T){let _=T.claims;if(!_?.sub||typeof _.sub!=="string")return;let j=Yo(_,T.expiresAt);if(T.authType==="sso")return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,sso:{profile:_,tenant:{id:jt(_,"idp")||jt(_,"iss"),name:jt(_,"iss")},tokenType:"Bearer",expires:j}};return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,userType:"customer",ciam:{profile:_,scope:"openid profile email",tokenType:"Bearer",expires:j}}}function Zo(T){if(T.authType!=="sso"&&T.authType!=="ciam")return;if(Ns(T))return;return{sid:T.sid,authType:T.authType,tenantId:typeof T.tenantId==="string"?T.tenantId:void 0,sub:T.sub,expiresAt:T.expiresAt,createdAt:T.createdAt,claims:Fo(T.claims)}}function Qo(T,_){if(!T.endsWith(".session"))return!1;if(!_||_.length===0)return!0;return _.some((j)=>T===`${j}.session`)}function ea(T){if(T===void 0)return;let _=(Array.isArray(T)?T:[T]).map((j)=>j.trim()).filter((j)=>j.length>0);return _.length>0?_:void 0}async function $s(T,_,j){return(await Ws(T,_,j)).map(Zo).filter((le)=>Boolean(le))}async function Ws(T,_,j){let X=Ho(T.headers.get("cookie")),le=ea(j?.cookiesPrefix),ge=[],ye=new Set;for(let[Se,he]of Object.entries(X)){if(!Qo(Se,le)||!he)continue;if(ye.has(he))continue;ye.add(he);let me=await _.get(he);if(!me)continue;if(me.authType!=="sso"&&me.authType!=="ciam")continue;if(Ns(me))continue;ge.push(me)}return ge}async function ta(T,_,j){return(await $s(T,_,j)).map(Xo).filter((le)=>Boolean(le))}var na="@ionite/core",ra=l(y(na));async function sa(T,_){let j=await Qt({idToken:T,jwksUri:_.jwksUri,issuer:_.issuer,audience:_.audience}),X=await ra.validate(j);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((ye)=>ye.message).join("; ")}`);let le=X.value;if(le===void 0)throw Error("ID token claims missing");return H(le)}function wt(T){return Date.now()-T}function Br(T){if(T instanceof Error)return{"error.name":T.name,"error.message":T.message};return{"error.name":typeof T,"error.message":String(T)}}function Qn(T,_){if(!T)return{};try{let j=new URL(T);return{[`${_}.origin`]:j.origin,[`${_}.path`]:j.pathname}}catch{return{[`${_}.path`]:T.startsWith("/")?T:`/${T}`}}}function er(T,_=5){if(!Array.isArray(T))return[String(T)];return T.slice(0,_).map((j)=>{if(!j||typeof j!=="object")return String(j);let X=j,le=Array.isArray(X.path)?X.path.join("."):String(X.path??""),ge=typeof X.message==="string"?X.message:String(X.message??"validation failed");return le?`${le}: ${ge}`:ge})}function ia(T){if(!T||typeof T!=="object")return{};let _=T;return{oidc_error:typeof _.error==="string"?_.error:void 0,oidc_error_description:typeof _.error_description==="string"?_.error_description:void 0,oidc_error_uri:typeof _.error_uri==="string"?_.error_uri:void 0}}function oa(T,_={}){let j=typeof T==="string"?T:T?.headers.get("cookie")??void 0;if(!j)return[];let le=`${_.cookiePrefix??"ion.sso"}.`,ge=new Set;for(let ye of Object.keys(ca(j))){if(!ye.startsWith(le))continue;let Se=ye.slice(le.length),he=Se.lastIndexOf(".");if(he<=0)continue;let me=Se.slice(0,he).trim();if(me)ge.add(me)}return Array.from(ge)}function aa(T,_,j,X,le){if(!j&&!X)return;let ge=new WeakMap,ye=new Map,Se={...j,...X},he=!!(Se.authority&&Se.tokenUrl&&Se.authorizationUrl&&Se.clientId&&Se.redirectUri&&Se.scope),me={...Se,authority:he?t(Se.authority,"Missing 'authority' from SSO Config"):Se.authority,tokenUrl:he?t(Se.tokenUrl,"Missing 'tokenUrl' from SSO Config"):Se.tokenUrl,authorizationUrl:he?t(Se.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):Se.authorizationUrl,clientId:he?t(Se.clientId,"Missing 'clientId' from SSO Config"):Se.clientId,redirectUri:he?t(Se.redirectUri,"Missing 'redirectUri' from SSO Config"):Se.redirectUri,scope:he?t(Se.scope,"Missing 'scope' from SSO Config"):Se.scope,responseType:Se.responseType??"code",cookiesSecure:Se.cookiesSecure!==void 0?Se.cookiesSecure:!0,cookiesSameSite:Se.cookiesSameSite!==void 0?Se.cookiesSameSite:"Strict",cookiesPrefix:Se.cookiesPrefix??(Se.clientId?`ion.sso.${Se.clientId}`:"ion.sso"),cookiesPath:Se.cookiesPath??"/",cookiesDomain:Nn(Se.cookiesDomain)},ze=Math.min(600,Math.max(0,Math.floor(Number(me.rotationGraceSeconds??60))||0))*1000,Je=Math.floor(Number(me.sessionWindowSeconds??86400)),Qe=Number.isFinite(Je)&&Je>=1?Je:86400;function ut(){let be=[];if(!me.authority)be.push("authority");if(!me.tokenUrl)be.push("tokenUrl");if(!me.authorizationUrl)be.push("authorizationUrl");if(!me.clientId)be.push("clientId");if(!me.redirectUri)be.push("redirectUri");if(!me.scope)be.push("scope");if(be.length>0)throw Error(`Missing OIDC configuration fields: ${be.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing ionite.`)}async function st(be){if(!me)throw Error("ionite SSO Manager not initialized");let Pe=ge.get(be);if(Pe)return Pe;let _e=Ne(be);return ge.set(be,_e),_e}async function Ne(be){try{let{tokens:Pe,session:_e,refreshedUser:fe}=await At(be);if(!Pe)return{status:"unauthenticated"};if(_e)Rn(be,"user",_e.entitlements);if(fe)return{status:"authenticated",value:fe};if(_e?.claims)return{status:"authenticated",value:Rt(_e.claims,Pe,xt(_e.expiresAt))};return{status:"unauthenticated"}}catch(Pe){if(Vs(Pe))return{status:"unauthenticated"};return _.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},Pe),{status:"degraded",error:Pe instanceof Error?Pe:void 0}}}async function Ve(be){let Pe=await st(be);return Pe.status==="authenticated"?Pe.value:void 0}async function tt(be){if(!me)throw Error("ionite SSO Manager not initialized");ut();let Pe=t(me.redirectUri,"Missing 'redirectUri' from SSO Config"),_e=t(me.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),fe=t(me.clientId,"Missing 'clientId' from SSO Config"),we=t(me.scope,"Missing 'scope' from SSO Config"),Te=me.cookiesSecure?be.url.replace(/^http:\/\//,"https://"):be.url,Ae=_t(),xe=_t(64),qe=_t(),We=Pe;try{new URL(We)}catch{if(Te)try{let Re=new URL(Te),Ee=We.startsWith("//")?We.slice(1):We.startsWith("/")?We:`/${We}`;We=new URL(Ee,Re.origin).toString()}catch{try{let Re=new URL(_e),Ee=We.startsWith("//")?We.slice(1):We.startsWith("/")?We:`/${We}`;We=new URL(Ee,Re.origin).toString()}catch{throw Error(`Invalid redirectUri: "${Pe}". It must be a valid absolute URL.`)}}}let ve=new URL(_e);ve.searchParams.append("client_id",fe),ve.searchParams.append("redirect_uri",We),ve.searchParams.append("response_type","code"),ve.searchParams.append("scope",we),ve.searchParams.append("state",Ae),ve.searchParams.append("nonce",qe);let ke=await Pn(xe);ve.searchParams.append("code_challenge",ke),ve.searchParams.append("code_challenge_method","S256");let Ce=await me.beforeLogin?.({request:be}),Ie=Ce===void 0?{state:Ae,codeVerifier:xe,nonce:qe}:{state:Ae,codeVerifier:xe,nonce:qe,context:Ce};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:ve.toString(),"Set-Cookie":Wt(He(Ae),Ie,me.loginStateTtl??600,"Lax")}})}async function Oe(be){if(!me)throw Error("ionite SSO Manager not initialized");let Pe;try{Pe=await Ve(be)}catch{Pe=void 0}let _e=await me.beforeLogout?.({request:be,user:Pe}),fe=Ze("session",be),we;try{we=await At(be);let ke=we.tokens?.refresh_token??Ze("refresh",be);if(ke)await Jt(ke)}catch(ke){_.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},ke)}if(me.sessionStore)try{let ke=we?.sid??fe;if(ke)await me.sessionStore.delete(ke)}catch(ke){_.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},ke)}let Te=Be(),Ae=await me.afterLogout?.({request:be,context:_e}),xe=en(Ae,"/",be.url);if(xe.response){let ke=new Headers(xe.response.headers);for(let[,Ce]of Te)ke.append("Set-Cookie",Ce);return new Response(xe.response.body,{status:xe.response.status,statusText:xe.response.statusText,headers:ke})}let qe=xe.location??"/",We=be.headers.get("accept");if(We?.includes(s)||We?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:qe}),{status:200,headers:[["Content-Type",s],...Te]});return new Response("Logged out",{status:302,headers:[["Location",qe],...Te]})}async function ct(be){if(!me)throw Error("ionite SSO Manager not initialized");if(!me.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!be.headers.get("content-type")?.includes(D))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let _e=await be.text(),we=new URLSearchParams(_e).get("logout_token");if(!we)return new Response("Missing logout_token parameter",{status:400});let Te=t(me.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),Ae=t(me.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),xe=me.jwksUri||`${Te}/protocol/openid-connect/certs`,qe=await Ir({logoutToken:we,jwksUri:xe,issuer:Te,audience:Ae,log:_}),We=typeof qe.sid==="string"?qe.sid:void 0;if(!We)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 me.sessionStore.delete(We),_.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:We}),new Response("OK",{status:200})}catch(Pe){return _.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},Pe),new Response("Internal Server Error",{status:500})}}async function ft(be){if(!me)throw Error("ionite SSO Manager not initialized");let Pe=Date.now(),_e=new URL(be.url),fe=new URLSearchParams(_e.search);_.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":be.method,"url.path":_e.pathname,hasCode:fe.has("code"),hasState:fe.has("state"),hasError:fe.has("error"),...Qn(fe.get("iss")??void 0,"oidc.issuer")});let we=Object.fromEntries(fe.entries()),Te=await T.callbackParams.validate(we);if(Te.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":er(Te.issues)}),ce(Te.issues,"OIDC callback parameters validation failed");let{code:Ae,state:xe}=Te.value,qe;try{let We=t(xe,'OIDC "state" was not present in the callback parameters'),ve=Ze(He(We),be,!0),{codeVerifier:ke,state:Ce,nonce:Ie,context:Re}=ve??{};qe=Re,_.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(ve),hasCodeVerifier:Boolean(ke),hasStateVerifier:Boolean(Ce),hasNonce:Boolean(Ie),hasContext:Re!==void 0});let Ee=t(ke,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');t(Ce,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let je=t(Ie,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),Ue=t(Ae,'OIDC "code" was not present in the callback parameters');if(xe!==Ce)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 Le=me.cookiesSecure?be.url.replace(/^http:\/\//,"https://"):be.url,Fe=await Ot(Ue,Ee,Le),{tokenExpiresAt:rt,sessionExpiresAt:at}=bt(Fe);Fe.expires=rt.toISOString();let pt=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 it=await gt(Fe,je,at);_.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(pt),"user.id":it.id});let et,mt;{let Ct=Ht("SSO requires sessionStore configuration for opaque session cookies."),Vt=typeof it.sso.profile.sid==="string"?it.sso.profile.sid:void 0,Mt=Vt||_t(32),vt=it.id;if(_.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(Mt),hasIdpSid:Boolean(Vt),hasSub:Boolean(vt),"user.id":vt}),!vt)throw Error("Session creation failed: missing sub in ID token claims");let qt=Date.now(),Cn=await rn({sid:Mt,sub:vt,idpSid:Vt,authType:"sso",tenantId:me.tenantId,tokens:Fe,claims:it.sso.profile,expiresAt:at,createdAt:new Date},vt,it.sso.profile,Fe);await ln(Ct,Cn),mt=Cn,et=["Set-Cookie",Wt("session",Mt,at)],_.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":wt(qt),"user.id":vt})}if(me.userStore)try{let Ct=it.id;if(Ct){let Vt=new Date,Mt=Date.now();_.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":Ct});let vt=await me.userStore.get(Ct);if(_.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":wt(Mt),"user.id":Ct,found:Boolean(vt)}),vt||me.enableJitUserProvisioning){let qt=Date.now(),Cn={...vt??{},...it,id:Ct,tenantId:vt?.tenantId,createdAt:vt?.createdAt??Vt,updatedAt:Vt};await me.userStore.upsert(Cn),_.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":wt(qt),"user.id":Ct,existing:Boolean(vt),jitProvisioning:Boolean(me.enableJitUserProvisioning)})}else _.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":Ct})}else _.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(Ct){_.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...Br(Ct)})}_.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":wt(Pe),"user.id":it.id});let nt=[["Set-Cookie",Xt(He(We))],...et?[et]:[],...et?await Ge(be,await Tt(it),at):[]],Et=await me.afterLogin?.({ok:!0,request:be,user:it,session:mt,context:qe,displayCookie:me.displayCookie,displayCookieAttributes:Ut()}),Dt=en(Et,"/",be.url);if(Dt.response)return on(Dt.response,nt.map(([,Ct])=>Ct));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",Dt.location],...nt]})}catch(We){_.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":wt(Pe),...Br(We)});let ve=xe?[["Set-Cookie",Xt(He(xe))]]:[],ke=await me.afterLogin?.({ok:!1,request:be,error:We,context:qe,displayCookie:me.displayCookie,displayCookieAttributes:Ut()}),Ce=en(ke,"/",be.url);if(Ce.response)return on(Ce.response,ve.map(([,Ie])=>Ie));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",Ce.location],...ve]})}}function bt(be){let Pe=Date.now(),_e=Number(be.expires_in??3600)||3600,fe=new Date(Pe+_e*1000),we;if(be.refresh_expires_in!=null&&Number.isFinite(Number(be.refresh_expires_in)))we=Number(be.refresh_expires_in);else if(be.refresh_token)we=Qe;else we=_e;return{tokenExpiresAt:fe,sessionExpiresAt:new Date(Pe+we*1000)}}async function gt(be,Pe,_e){if(!me)throw Error("ionite SSO Manager not initialized");let fe=Date.now(),we=await dn(be.id_token,Pe);return _.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(fe),"user.id":we.sub,hasEmail:Boolean(we.email),hasName:Boolean(we.name)}),Rt(we,be,_e)}function Rt(be,Pe,_e){let fe=_e??bt(Pe).sessionExpiresAt,we=be.ecid!==void 0&&be.ecid!==null?O(be.ecid):void 0;return{id:be.sub,userName:be.preferred_username||"",name:be.name||"",email:be.email||"",emails:[{value:be.email||"",primary:!0}],...we?{ecid:we}:{},avatar:be.picture,sso:{profile:{...be},tenant:{id:be.idp||be.iss||"",name:be.iss||""},scope:Pe.scope,tokenType:Pe.token_type,sessionState:Pe.session_state,expires:fe}}}async function Tt(be){if(!me.userStore)return be;let Pe=await me.userStore.lookup(be);if(!Pe)return be;return{...be,...Pe,id:be.id,sso:be.sso}}async function Ot(be,Pe,_e){if(!me)throw Error("ionite SSO Manager not initialized");ut();let fe=t(me.tokenUrl,"Missing 'tokenUrl' from SSO Config"),we=t(me.redirectUri,"Missing 'redirectUri' from SSO Config"),Te=t(me.clientId,"Missing 'clientId' from SSO Config"),Ae=we;try{new URL(Ae)}catch{if(_e)try{let qe=new URL(_e),We=Ae.startsWith("//")?Ae.slice(1):Ae.startsWith("/")?Ae:`/${Ae}`;Ae=new URL(We,qe.origin).toString()}catch{try{let qe=new URL(fe),We=Ae.startsWith("//")?Ae.slice(1):Ae.startsWith("/")?Ae:`/${Ae}`;Ae=new URL(We,qe.origin).toString()}catch{throw Error(`Invalid redirectUri: "${we}". It must be a valid absolute URL.`)}}}let xe=new URLSearchParams;if(xe.append("grant_type","authorization_code"),xe.append("code",be),xe.append("redirect_uri",Ae),xe.append("client_id",Te),me.clientSecret)xe.append("client_secret",me.clientSecret);xe.append("code_verifier",Pe);try{let qe=Date.now();_.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...Qn(fe,"oidc.token_url"),...Qn(Ae,"oidc.redirect_uri"),hasClientSecret:Boolean(me.clientSecret)});let We=await fetch(fe,{method:"POST",headers:{...h,...i},body:xe.toString()});_.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":We.status,"duration.ms":wt(qe)}),_.debug("SSO token exchange response body read started",{"ion.event":"ion.sso.token.response_body_read_started","ion.module":"sso","ion.operation":"token.exchange"});let ve=await a(We,{log:_,operation:"token.exchange"});if(_.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":wt(qe)}),!We.ok){_.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":We.status,"duration.ms":wt(qe),...ia(ve)});let Ce=ve;throw Error(`Token exchange failed: ${Ce.error||We.statusText} - ${Ce.error_description||""}`.trim())}let ke=await T.tokenResponse.validate(ve);if(ke.issues)throw _.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":wt(qe),"validation.issues":er(ke.issues)}),Error(`Token response validation failed: ${ke.issues}`);return _.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":wt(qe),tokenType:ke.value.token_type,hasAccessToken:Boolean(ke.value.access_token),hasIdToken:Boolean(ke.value.id_token),hasRefreshToken:Boolean(ke.value.refresh_token),expiresIn:ke.value.expires_in}),ke.value}catch(qe){throw _.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...Br(qe)}),qe}}async function wn(be){return kr(async()=>{if(!me)throw Error("ionite SSO Manager not initialized");ut();let Pe=t(me.tokenUrl,"Missing 'tokenUrl' from SSO Config"),_e=t(me.clientId,"Missing 'clientId' from SSO Config"),fe=new URLSearchParams;if(fe.append("grant_type","refresh_token"),fe.append("refresh_token",be),fe.append("client_id",_e),me.clientSecret)fe.append("client_secret",me.clientSecret);let we=await fetch(Pe,{method:"POST",headers:{...h,...i},body:fe.toString()}),Te=await a(we,{log:_,operation:"token.refresh"});if(!we.ok){_.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:Te});let xe=Te;throw Error(`Token refresh failed: ${xe.error||we.statusText} - ${xe.error_description||""}`.trim())}let Ae=await T.tokenResponse.validate(Te);if(Ae.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":er(Ae.issues)}),Error(`Token refresh response validation failed: ${Ae.issues}`);return Ae.value},void 0,void 0,void 0,_)}async function Jt(be){try{if(!me)throw Error("ionite SSO Manager not initialized");if(!me.revocationEndpoint)return;let Pe=t(me.clientId,"Missing 'clientId' from SSO Config"),_e=new URLSearchParams;if(_e.append("token",be),_e.append("token_type_hint","refresh_token"),_e.append("client_id",Pe),me.clientSecret)_e.append("client_secret",me.clientSecret);let fe=await fetch(me.revocationEndpoint,{method:"POST",headers:{...i,...h},body:_e.toString()});if(!fe.ok)_.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:fe.status,statusText:fe.statusText});else _.info("Token revoked successfully",{"ion.module":"sso"})}catch(Pe){_.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Pe)}}async function bn(){if(!me)throw Error("ionite SSO Manager not initialized");let be=me.authority;if(!me.jwksUri&&!be)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let Pe=me.jwksUri||`${be}/protocol/openid-connect/certs`;return Tn(Pe,_)}async function dn(be,Pe){let _e=Date.now(),fe=t(me.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),we=t(me.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),Te=me.jwksUri||`${fe}/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",...Qn(Te,"oidc.jwks_uri")});let Ae;try{Ae=await Qt({idToken:be,jwksUri:Te,issuer:fe,audience:we,expectedNonce:Pe,log:_})}catch(qe){throw _.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":wt(_e)},qe),qe}_.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":wt(_e)});let xe=await T.idTokenClaims.validate(Ae);if(xe.issues)throw _.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":wt(_e),"validation.issues":er(xe.issues)}),Error(`ID token claims validation failed: ${xe.issues}`);return _.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":wt(_e),"user.id":xe.value.sub,hasIssuer:Boolean(xe.value.iss),hasAudience:Boolean(xe.value.aud)}),xe.value}function Ht(be="SSO sessionStore is required for opaque session cookies."){if(!me.sessionStore)throw Error(be);return me.sessionStore}let Ft=!1;async function rn(be,Pe,_e,fe){let we=me.claimsAsEntitlements;if(!we?.claims?.length)return be;if(me.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Ft)Ft=!0,_.warn("SSO claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.sso.claims.incapable","ion.module":"sso","ion.outcome":"degraded"});return be}let Te=await vn({block:we,claims:_e,accessClaims:mn(fe?.access_token),scope:fe?.scope,subjectType:"user",subjectId:Pe,catalog:le?.catalogView?.(),log:_});return{...be,entitlements:Te}}async function ln(be,Pe){try{await be.create(Pe)}catch(_e){if(!await be.get(Pe.sid))throw _e;await be.update(Pe.sid,Pe)}}function xt(be){if(!be)return;if(be instanceof Date)return be;let Pe=new Date(be);return Number.isNaN(Pe.getTime())?void 0:Pe}function pn(be){let Pe=be.tokens;if(!Pe?.access_token||!Pe.id_token||!Pe.token_type)return;return Pe}async function Yt(be,Pe=!1){let _e=Ht(),fe=Ze("session",be);if(!fe)return{tokens:void 0,refreshHeaders:[]};let we=await _e.get(fe);if(we&&me.tenantId&&we.tenantId&&we.tenantId!==me.tenantId)return{tokens:void 0,refreshHeaders:Be(),sid:fe};if(we?.authType!=="sso")return{tokens:void 0,refreshHeaders:Be(),sid:fe};let Te=pn(we);if(!Te)return{tokens:void 0,refreshHeaders:Be(),sid:fe};let Ae=xt(we.expiresAt);if(Ae?Date.now()>Ae.getTime():!1)return await _e.delete(fe),{tokens:void 0,sid:fe,refreshHeaders:Be()};let qe=xt(Te.expires),We=qe?Date.now()>qe.getTime():!0;if((Pe||We)&&Te.refresh_token)return Pt(be,fe,we,Te);return{tokens:Te,sid:fe,session:we,refreshHeaders:Xe(be)}}function Pt(be,Pe,_e,fe){let we=ye.get(Pe);if(we)return we;let Te=Ht(),Ae=(async()=>{let xe=await wn(fe.refresh_token),{tokenExpiresAt:qe,sessionExpiresAt:We}=bt(xe);xe.expires=qe.toISOString();let ve=await gt(xe,void 0,We),ke=ve.sso.profile,Ce=_t(32),Ie=await rn({..._e,sid:Ce,tokens:xe,claims:ke,expiresAt:We,createdAt:new Date},_e.sub,ke,xe);await ln(Te,Ie);try{if(ze<=0)await Te.delete(Pe);else{let{refresh_token:Re,...Ee}=fe;await Te.update(Pe,{tokens:Ee,expiresAt:new Date(Date.now()+ze)})}}catch(Re){_.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},Re)}return{tokens:xe,sid:Ce,session:Ie,refreshedUser:ve,refreshHeaders:[["Set-Cookie",Wt("session",Ce,We)],...await Ge(be,ve,We)]}})();return ye.set(Pe,Ae),Ae.finally(()=>{ye.delete(Pe)})}async function At(be,Pe=!1){return Yt(be,Pe)}async function $t(be){let{tokens:Pe}=await At(be);if(!Pe)return;return Pe.access_token}function Wt(be,Pe,_e,fe=me.cookiesSameSite??"Strict"){if(!me)throw Error("ionite SSO Manager not initialized");if(be=`${me.cookiesPrefix}.${be}`,typeof Pe!=="string")Pe=btoa(JSON.stringify(Pe));let we;if(_e instanceof Date)we=`Expires=${_e.toUTCString()}`;else if(typeof _e==="number")we=`Max-Age=${_e}`;else throw Error("Invalid expires type",_e);if(Pe.length>4000)throw Error(`Error setting cookie: ${be}. Cookie length is: ${Pe.length}`);return`${be}=${Pe}; ${we}; Path=${me.cookiesPath};${Zt(me.cookiesDomain)} HttpOnly;${me.cookiesSecure?" Secure;":""} SameSite=${fe};`}function Xt(be){if(!me)throw Error("ionite SSO Manager not initialized");return`${me.cookiesPrefix}.${be}=; Max-Age=0; Path=${me.cookiesPath};${Zt(me.cookiesDomain)} HttpOnly;${me.cookiesSecure?" Secure;":""} SameSite=${me.cookiesSameSite};`}function Ut(){return{path:me.cookiesPath??"/",domain:me.cookiesDomain,secure:me.cookiesSecure!==!1,sameSite:me.cookiesSameSite??"Strict"}}function Be(){return[["Set-Cookie",Xt("session")],["Set-Cookie",Bt(`${me.cookiesPrefix}.profile`,Ut())]]}function Xe(be){if(me.displayCookie?.enabled===!0)return[];return gn(be.headers.get("cookie"),me.cookiesPrefix??"ion.sso",Ut()).map((Pe)=>["Set-Cookie",Pe])}async function Ge(be,Pe,_e){return(await An({cookieHeader:be.headers.get("cookie"),sessionStore:me.sessionStore,cookiesPrefix:me.cookiesPrefix??"ion.sso",authType:"sso",tenantId:me.tenantId,expiresAt:_e,user:Pe,projector:me.displayUser,displayCookie:me.displayCookie,trim:me.trimDisplayCookies,attr:Ut()})).map((we)=>["Set-Cookie",we])}function Ze(be,Pe,_e=!1){if(!me)throw Error("ionite SSO Manager not initialized");let fe=Pe.headers.get("cookie");if(!fe)return null;let we=`${me.cookiesPrefix}.${be}`,Te=fe.split(";").find((We)=>We.trim().startsWith(`${we}=`));if(!Te)return null;let Ae=Te.indexOf("="),xe=Te.slice(Ae+1).trim();if(!_e)return xe;let qe=atob(xe);return JSON.parse(qe)}function He(be){return`state_${be}`}async function Ye(be,Pe){if(!me)throw Error("ionite SSO Manager not initialized");let{loginUrl:_e,userUrl:fe,tokenUrl:we,refreshUrl:Te,logoutUrl:Ae,logoutBackChannelUrl:xe,jwksUrl:qe,redirectUri:We}={...me,...Pe},ve=new URL(be.url).pathname;if(We){let ke;try{ke=new URL(We).pathname}catch{try{let Ce=new URL(be.url),Ie=We.startsWith("//")?We.slice(1):We;ke=new URL(Ie,Ce.origin).pathname}catch{ke=We.startsWith("/")?We:`/${We}`}}if(ke===ve)return ft(be)}if(_e===ve)return tt(be);if(fe===ve){if((me.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Xe(be)});try{let{tokens:ke,session:Ce,refreshedUser:Ie,refreshHeaders:Re}=await At(be);if(!ke)return new Response("User not logged in",{status:401,headers:Re});let Ee=Ie??(Ce?.claims?Rt(Ce.claims,ke,xt(Ce.expiresAt)):void 0);if(!Ee)return new Response("User not logged in",{status:401,headers:Re});let je=await Tt(Ee),Ue=`${me.cookiesPrefix}.profile`,Le=xt(Ce?.expiresAt),Fe=me.displayCookie?.enabled===!0&&Le&&!Ze("profile",be)&&!Re.some(([,at])=>at.startsWith(`${Ue}=`))?await Ge(be,je,Le):[],rt=me.userEndpoint==="display"?m(je,me.displayUser):je;return new Response(JSON.stringify(rt),{headers:[["Content-Type",s],...Re,...Fe]})}catch(ke){if(Vs(ke))return new Response("User not logged in",{status:401});return _.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},ke),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r})}}if(we===ve){let{tokens:ke,refreshHeaders:Ce}=await At(be);if(!ke)return new Response("User not logged in",{status:401,headers:Ce});return new Response(JSON.stringify({token:ke.access_token,expires:ke.expires}),{headers:[["Content-Type",s],...Ce]})}if(Te===ve){let{tokens:ke,refreshHeaders:Ce}=await At(be,!0);if(!ke)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:Ce})}if(Ae===ve)return Oe(be);if(xe===ve)return ct(be);if(qe===ve){let ke=await bn();return new Response(JSON.stringify(ke),{headers:[["Content-Type",s]]})}return new Response("Not Found",{status:404})}let dt;return dt={...me,describe:()=>({module:"sso",active:!0,ready:dt.isReady?.()??!0,authority:me.authority,tokenUrl:me.tokenUrl,authorizationUrl:me.authorizationUrl,clientId:me.clientId,redirectUri:me.redirectUri,responseType:me.responseType,scope:me.scope,silentRedirectUri:me.silentRedirectUri,jwksUri:me.jwksUri,endSessionEndpoint:me.endSessionEndpoint,revocationEndpoint:me.revocationEndpoint,cookies:{prefix:me.cookiesPrefix,path:me.cookiesPath,secure:me.cookiesSecure,sameSite:me.cookiesSameSite,domain:me.cookiesDomain},loginStateTtl:me.loginStateTtl,rotationGraceSeconds:me.rotationGraceSeconds,sessionWindowSeconds:me.sessionWindowSeconds,displayCookie:me.displayCookie,jit:{enabled:me.enableJitUserProvisioning===!0,userStore:me.userStore!==void 0},sessionStore:me.sessionStore!==void 0,...me.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...me.claimsAsEntitlements.claims],expand:me.claimsAsEntitlements.expand===!0,resources:me.claimsAsEntitlements.expand===!0&&me.claimsAsEntitlements.resources===!0,capable:me.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},urls:{loginUrl:me.loginUrl??"",userUrl:me.userUrl??"",logoutUrl:me.logoutUrl??"",logoutBackChannelUrl:me.logoutBackChannelUrl??"",refreshUrl:me.refreshUrl??"",callbackUrl:me.redirectUri??""}}),getUser:Ve,resolveUser:st,getJwt:$t,initiateLogin:tt,logout:Oe,logoutBackChannel:ct,callbackHandler:ft,handler:Ye},dt}function ca(T){let _={},j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;let ye=le.slice(0,ge).trim(),Se=le.slice(ge+1).trim();_[ye]=Se}return _}function Vs(T){if(!(T instanceof Error))return!1;return["Public key not found","Invalid JWT","Invalid JWT signature","ID token expired","ID token issuer mismatch","ID token audience mismatch","ID token nonce mismatch","ID token missing exp","invalid_grant"].some((_)=>T.message.includes(_))}function qs(T){return T=T??"SSO Unavailable",new Response(JSON.stringify({error:T}),{status:503,statusText:T,headers:r})}var tr="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function ua(T,_){return t(_,tr),_.sso?.getUser(T)}async function Gr(T,_){return t(_,tr),await _.sso?.resolveUser(T)??{status:"unauthenticated"}}async function da(T,_){t(_,tr);let j=_.sso;if(!j)return qs();return j.initiateLogin(T)}async function la(T,_){t(_,tr);let j=_.sso;if(!j)return qs();return j.callbackHandler(T)}var Jr="tenant.owner",Kr="tenant.owner.",pa="tenant:";function ma(T){return{id:Jr,name:"Tenant owner",description:"Administer one tenant resource",requestable:!1,permissionTypes:["Admin"],resourceTypes:["tenant"],assignableSubjectTypes:["customer"],...T}}function Hr(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${pa}${_}`}function fa(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${Kr}${_}`}function yt(T){return{allow:!1,reason:T,response(){if(T==="not_found")return Response.json({error:"Not Found"},{status:404});if(T==="forbidden")return Response.json({error:"Forbidden"},{status:403});if(T==="unavailable")return Response.json({error:"Tenant runtime unavailable"},{status:503});return Response.json({error:"Unauthorized"},{status:401})}}}function nr(T,_){if(!T.id)return yt("unavailable");return{allow:!0,session:{id:T.id,email:T.email,name:T.name,kind:_}}}function zs(T){return T==="access_index_not_configured"||T==="error"}async function Bs(T,_){let j;try{j=await zn(T,_.rootIon)}catch{return yt("unavailable")}if(j.status==="degraded")return yt("unavailable");if(j.status==="unauthenticated")return yt("unauthenticated");if(!j.value.id)return yt("unavailable");try{let X=await _.rootIon.authz.hasPermission(j.value.id,_.ownerPermission??Jr,Hr(_.tenantId),"customer");if(X.allow)return nr(j.value,"owner");return yt(zs(X.metadata?.reason)?"unavailable":"forbidden")}catch{return yt("unavailable")}}async function ga(T,_){let{tenantIon:j}=_;if(!j)return yt("not_found");if(j.isReady()){let le;try{le=await Gr(T,j)}catch{return yt("unavailable")}if(le.status==="degraded")return yt("unavailable");if(le.status==="authenticated"){if(!le.value.id)return yt("unavailable");if(!_.permission)return nr(le.value,"sso");try{let ge=await j.authz.hasPermission(le.value.id,_.permission,void 0,"user");if(ge.allow)return nr(le.value,"sso");return yt(zs(ge.metadata?.reason)?"unavailable":"forbidden")}catch{return yt("unavailable")}}if(_.allowTenantCustomer){let ge;try{ge=await zn(T,j)}catch{return yt("unavailable")}if(ge.status==="degraded")return yt("unavailable");if(ge.status==="authenticated"){if(!ge.value.id)return yt("unavailable");return nr(ge.value,"customer")}}}let X=await Bs(T,_);if(X.allow||X.reason==="unavailable")return X;if(!j.isReady())return yt("unavailable");return yt("unauthenticated")}async function ya(T,_){let j=T.authz.accessStore;if(!j)throw Error("Cannot list owned tenants: no AccessAssignmentStore is wired.");let X=new Set;for await(let le of c((ge,ye)=>j.listBySubject(_,"customer",{start:ge,limit:ye}))){let ge=typeof le.target==="string"?le.target:le.target.id;if(le.targetType!=="group"||!ge.startsWith(Kr))continue;let ye=ge.slice(Kr.length);if(!ye||!le.resources?.includes(Hr(ye)))continue;X.add(ye)}return[...X].sort()}function ha(T,_){let j=_.redirectTo.trim()||"/",X=_.tenantIon?.sso?.isReady?.()===!0?`${_.tenantIonBasePath?.(T)??`/api/${encodeURIComponent(T)}/ionite`}/auth/login`:_.fallbackPath,le=new URL(X,"http://localhost");return le.searchParams.set("redirect",j),`${le.pathname}${le.search}`}export{_n as CACHE_BOUNDS,Qr as CIAM_PROVIDER_PRESETS,Q as CatalogAdjacencyCache,Me as InMemoryTenantStore,br as MICROSOFT_CONSUMERS_TENANT_ID,Jr as TENANT_OWNER_PERMISSION,zi as allowHosts,qi as allowOrigins,hs as allowRelativePaths,ks as allowSameOrigin,xs as assertSubjectTypeAssignable,ms as assertTrustedIdTokenClaims,Or as baseCustomerToScim,Dr as baseUserToScimUser,Mr as baseWorkloadToScim,ys as blockDangerousUrls,vr as buildAuthorizationUrl,zr as buildLfvSigningInput,la as callback,Gi as captureRedirect,Fi as ciam,Li as clearDiscoveryCache,Ai as clearJwksCache,$e as collectReferencedDefinitions,wi as configureJwksCache,mn as decodeUnverifiedJwtPayload,Bi as defaultRedirectPolicies,vn as deriveClaimsEntitlements,sr as derivedEntitlementsFor,Vn as discoverOidcEndpoints,Ws as discoverSessionRecords,$s as discoverSessions,Er as entitlementToScimGroup,Rr as exchangeAuthorizationCode,E as expandRoot,Tr as fetchUserInfo,Bt as formatDisplayClearCookie,pr as formatDisplaySetCookie,xr as generateAppleClientSecret,Vo as generateLfvEd25519KeyPair,Sr as getCachedVerificationKey,Yi as getCustomer,ta as getDiscoveredSessionUsers,Tn as getJwks,ya as getOwnedTenantIds,ar as getProviderPreset,xi as getPublicKeyForKid,Ti as getPublicKeyFromJwks,ua as getUser,wr as getVerificationKeyForKid,ai as has,pi as hasAll,gi as hasAllScope,li as hasAny,fi as hasAnyScope,di as hasGroup,ci as hasPermission,ui as hasRole,mi as hasScope,Mo as iam,da as initiateLogin,Ar as isMicrosoftMultiTenantAuthority,Ss as isRedirectAllowed,oa as listSsoClientIdsFromCookies,ps as matchesMicrosoftIssuer,Wn as microsoftIssuerTenantId,sn as normalizeOidcIssuer,ur as orderedEnabledProviders,Ps as parseLfvJwks,Pn as pkceChallengeFromVerifier,Si as planDiscoveredTenantCookies,gn as planDisplayCookieClear,An as planDisplayCookieHeaders,pe as reconcileSubjectAccess,Rn as rememberDerivedEntitlements,en as resolveAfterRedirect,qo as resolveCacheConfig,Ki as resolveCapturedRedirect,Ln as resolveCiamProvider,zn as resolveCustomer,Ii as resolveJwkForKid,Us as resolveJwksCacheConfig,cr as resolveProviderBranding,Ur as resolveRedirect,Es as resolveSessionCacheConfig,Bs as resolveTenantOwner,ga as resolveTenantSession,Gr as resolveUser,Pr as sameOriginRedirectRules,ns as selectDisplayCookies,ot as sendTenantWebhook,ji as setDiscoveryClock,bi as setJwksClock,Ci as setJwksRetry,Ko as signCompactJwt,Wo as signLfvPayload,aa as sso,Go as staticSigningKeyRing,jo as stringifyLfvJwks,ha as tenantAccessLoginUrl,fa as tenantOwnerEntitlementId,ma as tenantOwnerPermission,Hr as tenantResourceId,Jo as verifyCompactJwt,Qt as verifyIdToken,$o as verifyLfvSignature,Ir as verifyLogoutToken,sa as verifyUser,on as withSetCookies};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionite/core",
3
- "version": "0.0.24-beta.20261006.21",
3
+ "version": "0.0.24-beta.20261006.22",
4
4
  "description": "ionite Core (client-safe main entry; server handlers under ./server)",
5
5
  "private": false,
6
6
  "author": "ionite",