@enterprisestandard/server 0.0.8-beta.20260301.3 → 0.0.8
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.js +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createValidators as iL,defaultLogger as mS,tenant as pL}from"@enterprisestandard/core";import{ciam as tL,iam as rL,sso as aL}from"@enterprisestandard/core/server";function ZS(S){throw Error("Not implemented")}function GS(S){throw Error("Not implemented")}function PS(S){return console.warn("ES_CONFIG_TYPE is not set. For LLM documentation, see https://enterprisestandard.com/llms.txt"),console.warn(`If this is a local development environment, visit https://ionite.com/dev?appId=${S.appId??""} to get started, or run: npx @enterprisestandard/cli`),{load:async()=>{return{}},subscribe(L){let $=()=>{};return()=>{}}}}function MS(S){throw Error("Not implemented")}var DS=new Map;function _L(S){if(!S)return"/";return S.startsWith("/")?S:`/${S}`}function YL(S){try{let L=new URL(S),$=L.pathname.replace(/\/+$/g,"");return`${L.origin}${$}`}catch{return S.replace(/\/+$/g,"")}}function uS(S){let L=YL(S.lfvServerUrl),$=_L(S.path);return`${L}|${$}`}function hS(S,L,$){let R=DS.get(S)??new Map;return R.set(L,$),DS.set(S,R),()=>{let U=DS.get(S);if(!U)return;if(U.delete(L),U.size===0)DS.delete(S)}}async function dS(S,L,$){let R=DS.get(S);if(!R)return 0;let U=0;for(let[D,X]of R){if($&&D===$)continue;if(!X.onDelivery)continue;U+=1,await X.onDelivery(L)}return U}async function cS(S,L,$){let R=DS.get(S);if(!R)return 0;let U=0;for(let[D,X]of R){if($&&D===$)continue;if(!X.onEvents)continue;U+=1,await X.onEvents(L)}return U}function nS(S){try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}var XL=1e4,ZL=1e4;async function GL(S){await new Promise((L)=>setTimeout(L,S))}function e(S){return{startedAt:Date.now(),timeout:typeof S?.timeout==="number"&&S.timeout>0?S.timeout:void 0}}function gS(S){if(S.timeout===void 0)return;let L=Date.now()-S.startedAt;return Math.max(0,S.timeout-L)}function QS(S,L,$){return Error(`LFV ${S} timed out after ${$.timeout??0}ms for ${L}`)}async function YS(S,L,$,R,U){let D=gS($);if(D!==void 0){if(D<=0)throw QS(R,U,$);let X=new AbortController,F=setTimeout(()=>X.abort(),D);try{return await fetch(S,{...L,signal:X.signal})}catch(z){if(z instanceof Error&&z.name==="AbortError")throw QS(R,U,$);throw z}finally{clearTimeout(F)}}return await fetch(S,L)}async function fS(S,L,$,R,U,D){let X=0,F=Date.now();for(;;){let z=gS(L);if(z!==void 0&&z<=0)throw QS(R,$,L);try{return await S()}catch(Z){if(X+=1,D>0&&Date.now()-F>=D){let K=Z instanceof Error?Z.message:String(Z);console.warn(`Error connecting to the LFV source. Retries: '${X}' Error: ${K}`),F=Date.now()}let Q=z===void 0?U:Math.min(U,z);if(Q<=0)throw QS(R,$,L);await GL(Q)}}}function ML(S){return typeof S==="object"&&S!==null&&!Array.isArray(S)}function zS(S){let{lfvServerUrl:L,clientId:$,path:R}=S,U=S.signature??"sdk-placeholder-signature",D=typeof S.deliveryTimeout==="number"&&S.deliveryTimeout>0?S.deliveryTimeout:void 0,X=typeof S.retryInterval==="number"&&S.retryInterval>0?S.retryInterval:XL,F=typeof S.warnInterval==="number"&&S.warnInterval>=0?S.warnInterval:ZL,z=nS(S.deliveryEndpoint),Z=nS(S.eventsEndpoint),Q=uS({lfvServerUrl:L??"",path:R??""}),K=crypto.randomUUID(),T=new Map,y=new Map,d=new Map,H;function O(){let _=T.size>0,Y=d.size>0,B=_||Y;if(B&&!H){H=hS(Q,K,{onDelivery:async(A)=>{j(A)},onEvents:async(A)=>{W(A)}});return}if(!B&&H)H(),H=void 0}function q(_){if(!L)throw Error(`LFV source requires "lfvServerUrl" for path ${_}`);if(!$)throw Error(`LFV source requires "clientId" for path ${_}`);return{lfvUrl:L,clientId:$}}async function V(_){return _.text().catch(()=>"")}async function k(_,Y,B,A){let w=q(_),c=B??crypto.randomUUID(),C=A??e(),n={request_id:c,path:_,action:Y},f=await fS(async()=>{return await YS(`${w.lfvUrl.replace(/\/+$/g,"")}/clients/${w.clientId}/otp`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":c,"X-LFV-Signature":U},body:JSON.stringify(n)},C,"issueOtp",_)},C,_,"issueOtp",X,F);if(f.status!==200){let p=await V(f);throw Error(`LFV OTP request failed (${f.status}) for ${_}: ${p}`)}let SS=await f.json();if(!SS.otp)throw Error(`LFV OTP response missing otp for ${_}`);return SS.otp}async function g(_,Y,B,A,w,c){let C=q(Y),n=w??crypto.randomUUID(),f=c??e(),SS=await k(Y,B,n,f),p=await fS(async()=>{return await YS(`${C.lfvUrl.replace(/\/+$/g,"")}${_}`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":n,"X-LFV-Signature":U},body:JSON.stringify({request_id:n,otp:SS,path:Y,...A??{}})},f,B,Y)},f,Y,B,X,F);if(p.status!==200&&p.status!==202){let XS=await V(p);throw Error(`LFV ${B} failed (${p.status}) for ${Y}: ${XS}`)}return{requestId:n}}async function t(_,Y,B){let A=y.get(_);if(A)return A;let w=e(B),c=B?.timeout??D,C,n=new Promise((SS,p)=>{if(C={resolve:SS,reject:p},c!==void 0&&c>0)C.timeout=setTimeout(()=>{if(C){let AS=d.get(_);if(AS?.delete(C),AS&&AS.size===0)d.delete(_);O()}p(Error(`LFV delivery timed out while reading ${_}`))},c);let XS=d.get(_)??new Set;XS.add(C),d.set(_,XS),O()}),f=Y??crypto.randomUUID();try{await g("/secrets/request",_,"read_secret",void 0,f,w)}catch(SS){if(C){if(C.timeout)clearTimeout(C.timeout);let p=d.get(_);if(p?.delete(C),p&&p.size===0)d.delete(_);O()}throw SS}return await n}function s(_,Y){y.set(_,Y);let B=T.get(_);if(!B)return;for(let A of B)A(Y)}async function i(_,Y){return await t(_,void 0,Y)}async function US(_,Y,B){if(!ML(Y))throw Error(`putSecret requires an object value for LFV source at path ${_}`);let A=e(B);if(await x(_,B)){await g("/secrets/update",_,"update_secret",{data:Y},void 0,A);return}await g("/secrets/create",_,"create_secret",{data:Y},void 0,A)}async function P(_,Y){let B=e(Y);await g("/secrets/delete",_,"delete_secret",void 0,void 0,B)}async function u(_,Y){let B=q(_),A=e(Y),w=crypto.randomUUID(),c=await k(_,"list_paths",w,A),C=await YS(`${B.lfvUrl.replace(/\/+$/g,"")}/paths/list`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":w,"X-LFV-Signature":U},body:JSON.stringify({request_id:w,otp:c,path:_})},A,"listPaths",_);if(C.status!==200){let f=await V(C);throw Error(`LFV listPaths failed (${C.status}) for ${_}: ${f}`)}let n=await C.json();if(!Array.isArray(n.items))throw Error(`LFV listPaths returned invalid payload for ${_}`);return n.items.filter((f)=>typeof f==="string")}async function x(_,Y){let B=q(_),A=e(Y),w=crypto.randomUUID(),c=await k(_,"read_metadata",w,A),C=await YS(`${B.lfvUrl.replace(/\/+$/g,"")}/paths/exists`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":w,"X-LFV-Signature":U},body:JSON.stringify({request_id:w,otp:c,path:_})},A,"exists",_);if(C.status!==200){let f=await V(C);throw Error(`LFV exists failed (${C.status}) for ${_}: ${f}`)}let n=await C.json();if(typeof n.exists!=="boolean")throw Error(`LFV exists returned invalid payload for ${_}`);return n.exists}async function v(_,Y,B){let A=e(B);await g("/secrets/rotate/request",_,"request_rotate",{reason:Y?.reason,severity:Y?.severity,incident_ref:Y?.incidentRef},void 0,A)}async function b(_,Y,B){let A=e(B);await g("/secrets/revoke/request",_,"request_revoke",{reason:Y?.reason,severity:Y?.severity,incident_ref:Y?.incidentRef},void 0,A)}async function h(_,Y){let B=q(_),A=e(Y),w=crypto.randomUUID(),c=await k(_,"read_metadata",w,A),C=await YS(`${B.lfvUrl.replace(/\/+$/g,"")}/paths/metadata/read`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":w,"X-LFV-Signature":U},body:JSON.stringify({request_id:w,otp:c,path:_})},A,"getMetadata",_);if(C.status!==200){let f=await V(C);throw Error(`LFV getMetadata failed (${C.status}) for ${_}: ${f}`)}let n=await C.json();if(!n.metadata||typeof n.metadata!=="object")throw Error(`LFV getMetadata returned invalid payload for ${_}`);return n.metadata}function I(_,Y){let B=T.get(_)??new Set;B.add(Y),T.set(_,B);let A=y.get(_);if(A)Y(A);return O(),()=>{let w=T.get(_);if(!w)return;if(w.delete(Y),w.size===0)T.delete(_);O()}}function m(_){return _.method==="POST"&&new URL(_.url).pathname===z}function M(_){return _.method==="POST"&&new URL(_.url).pathname===Z}function G(_){let Y=_.data?.metadata?.path;if(typeof Y==="string"&&Y)return Y;if(typeof _.path==="string"&&_.path)return _.path;return}function N(_,Y){let B=d.get(_);if(!B||B.size===0)return!1;d.delete(_),O();for(let A of B){if(A.timeout)clearTimeout(A.timeout);A.resolve(Y)}return!0}function j(_){let Y=G(_);if(!Y)return{handled:!1};let B=_.data?.metadata??{},A=typeof B.version==="number"?B.version:0,w={data:_.data?.data??{},metadata:{path:Y,version:A,created:new Date}};return s(Y,w),{handled:N(Y,w)}}async function J(_){let Y=await _.json(),B=j(Y),A=await dS(Q,Y,K);if(!B.handled&&A===0)return new Response(JSON.stringify({status:"accepted",note:"unmapped_delivery"}),{status:200,headers:{"Content-Type":"application/json"}});return new Response(JSON.stringify({status:"accepted"}),{status:200,headers:{"Content-Type":"application/json"}})}function W(_){if(!_?.path||typeof _.path!=="string")return;if(_.event==="created"||_.event==="updated"||_.event==="rotated"||_.event==="revoked")t(_.path,_.request_id).catch(()=>{})}async function E(_){let Y=await _.json();if(!Y?.path||typeof Y.path!=="string")return new Response(JSON.stringify({error:"invalid_request",message:"path is required"}),{status:400,headers:{"Content-Type":"application/json"}});return W(Y),await cS(Q,Y,K),new Response(JSON.stringify({status:"accepted"}),{status:200,headers:{"Content-Type":"application/json"}})}return{type:S.type,getFullSecret:i,getSecret:async(_,Y)=>{return(await i(_,Y)).data},putSecret:US,deleteSecret:P,listPaths:u,exists:x,requestRotate:v,requestRevoke:b,getMetadata:h,subscribe:I,isDeliveryRequest:m,isEventsRequest:M,handleDelivery:J,handleEvents:E}}function LS(S,L,$){if(typeof S!=="string"||S.trim()==="")throw Error(`"${L}" is required when using ${$}`);return S}var VS="__esLfvBootstrap";function OS(S){let L=LS(S.path,"path","lfvConfig"),$=LS(S.deliveryEndpoint,"deliveryEndpoint","lfvConfig"),R=LS(S.eventsEndpoint,"eventsEndpoint","lfvConfig"),U={type:"lfv",path:L,lfvServerUrl:S.lfvServerUrl,clientId:S.clientId,signature:S.signature,deliveryTimeout:S.deliveryTimeout,retryInterval:S.retryInterval,warnInterval:S.warnInterval,deliveryEndpoint:$,eventsEndpoint:R,verifyPublicKey:S.verifyPublicKey},D=S.vault??zS({type:"lfv",path:L,lfvServerUrl:LS(S.lfvServerUrl,"lfvServerUrl","lfvConfig"),clientId:LS(S.clientId,"clientId","lfvConfig"),signature:S.signature,deliveryTimeout:S.deliveryTimeout,retryInterval:S.retryInterval,warnInterval:S.warnInterval,deliveryEndpoint:$,eventsEndpoint:R,verifyPublicKey:S.verifyPublicKey}),X={load:async()=>{try{return(await D.getFullSecret(L)).data}catch(F){throw Error("Error retrieving remote config from LFV",{cause:F})}},subscribe:(F)=>{return D.subscribe(L,(z)=>{F(z.data)})}};return X[VS]=U,X}import{readFile as QL}from"node:fs";import{parseJsonc as zL}from"@enterprisestandard/core";function IS(S){let L=S.path??"es-config.jsonc",$=S.watch===!0;return{load:()=>{return new Promise((U,D)=>{QL(L,"utf-8",(X,F)=>{if(X){D(Error(`Failed to read config file "${L}": ${X.message}`));return}try{U(zL(F))}catch(z){let Z=z instanceof Error?z.message:String(z);D(Error(`Invalid JSON/JSONC in "${L}": ${Z}`))}})})},subscribe(U){throw Error("TODO: subscribe not implemented for local file config source")}}}function _S(S){let{type:L="vault",url:$,token:R,ttl:U}=S;if(!$)throw Error("OpenBao/Hashicorp compatible vaults require a non-empty url");if(!R)console.log("OpenBao/Hashicorp compatible vaults usually require a token, but one was not provided. Vault requests may fail.");if(U&&U<600000)throw Error("OpenBao/Hashicorp compatible vaults require ttl to be set and greater than 600_000 milliseconds (10 minutes), as not to overload the vault with polling requests");let D={"Content-Type":"application/json"};if(R)D["X-Vault-Token"]=R;function X(H){return typeof H==="object"&&H!==null&&!Array.isArray(H)}async function F(H,O){let q=await fetch(`${$}/${H}`,{headers:{...D}});if(q.status!==200){let k=q.status===401||q.status===403?`Vault returned ${q.status} ${q.statusText} (auth error) from URL: ${$}/${H}`:`Vault returned invalid status, ${q.status}: '${q.statusText}' from URL: ${$}/${H}`;throw Error(k)}try{return(await q.json()).data}catch(V){throw Error("Error retrieving secret",{cause:V})}}async function z(H,O,q){if(!X(O))throw Error(`putSecret requires an object value for vault source at path ${H}`);let V=await fetch(`${$}/${H}`,{method:"POST",headers:D,body:JSON.stringify(O)});if(V.status!==200&&V.status!==201&&V.status!==204){let k=await V.text().catch(()=>"");throw Error(`Vault putSecret failed (${V.status}) for ${$}/${H}: ${k}`)}}async function Z(H,O){let q=await fetch(`${$}/${H}`,{method:"DELETE",headers:D});if(q.status!==200&&q.status!==202&&q.status!==204){let V=await q.text().catch(()=>"");throw Error(`Vault deleteSecret failed (${q.status}) for ${$}/${H}: ${V}`)}}async function Q(H,O){let q=`${$}/${H}`,V=async(s)=>{if(s==="LIST")return fetch(q,{method:"LIST",headers:D});let i=q.includes("?")?"&":"?";return fetch(`${q}${i}list=true`,{method:"GET",headers:D})},k=await V("LIST");if(k.status===405||k.status===501)k=await V("GET");if(k.status!==200){let s=await k.text().catch(()=>"");throw Error(`Vault listPaths failed (${k.status}) for ${$}/${H}: ${s}`)}let g=await k.json().catch(()=>null),t;if(g&&typeof g==="object"){let s=g,i=s.data;if(i&&typeof i==="object")t=i.keys;else t=s.keys}if(!Array.isArray(t))throw Error(`Vault listPaths returned an unexpected response for ${$}/${H}`);return t.filter((s)=>typeof s==="string")}async function K(H,O){let q=await fetch(`${$}/${H}`,{headers:D});if(q.status===200)return!0;if(q.status===404)return!1;if(q.status===401||q.status===403)throw Error(`Vault exists failed (${q.status}) for ${$}/${H}: permission denied`);let V=await q.text().catch(()=>"");throw Error(`Vault exists failed (${q.status}) for ${$}/${H}: ${V}`)}async function T(H,O,q){throw Error(`Vault requestRotate is not implemented for source ${L} at path ${H}`)}async function y(H,O,q){throw Error(`Vault requestRevoke is not implemented for source ${L} at path ${H}`)}async function d(H,O){return(await F(H,O)).metadata}return{type:L,getFullSecret:F,getSecret:async(H,O)=>{return(await F(H,O)).data},putSecret:z,deleteSecret:Z,listPaths:Q,exists:K,requestRotate:T,requestRevoke:y,getMetadata:d,subscribe:(H,O)=>{if(!U)return console.warn("OpenBao/Hashicorp compatible vaults require ttl to be set if you want to subscribe to changes"),()=>{};let q,V=setInterval(async()=>{try{let k=await F(H);if(q===void 0){q=k.metadata.version;return}if(k.metadata.version!==q)q=k.metadata.version,O(k)}catch(k){console.warn(`Error retrieving remote config from vault. Retrying in ${S.ttl} milliseconds`,k)}},U);return()=>clearInterval(V)}}}function sS(S){if(!S||typeof S!=="object"||Array.isArray(S))return{};let L=S;if(!(("tenantId"in L)||("sso"in L)||("iam"in L)||("workload"in L)||("secrets"in L)||("tenant"in L)||("ciam"in L))&&Object.keys(L).length===1&&"data"in L){let R=L.data;if(R&&typeof R==="object"&&!Array.isArray(R))return R}return L}function NS(S){let L=LS(S.path,"path","vaultConfig"),$=S.vault??_S({type:"vault",url:S.url,token:S.token,ttl:S.ttl});return{load:async()=>{try{let R=await $.getFullSecret(L);return sS(R.data)}catch(R){if(!S?.retryInterval)throw Error("Error retrieving remote config from vault",{cause:R});else return console.warn(`Error retrieving remote config from vault. Retrying in ${S.ttl} seconds`,R),{}}},subscribe:(R)=>{return $.subscribe(L,(U)=>{R(sS(U.data))})}}}function WS(S){if(!S)return;let L=Number.parseInt(S,10);return Number.isFinite(L)?L:void 0}function xS(S){let L=S?.type??process.env.ES_CONFIG_TYPE;if(!L||L==="dev"){let $=S??{};return PS({appId:$?.appId??process.env.ES_APP_ID,path:process.env.ES_CONFIG_PATH??$?.path,ioniteUrl:process.env.ES_IONITE_URL??$?.ioniteUrl})}else if(L==="lfv"){let $=S??{};return OS({path:process.env.ES_LFV_PATH??$?.path,lfvServerUrl:process.env.ES_LFV_SERVER_URL??$?.lfvServerUrl,clientId:process.env.ES_LFV_CLIENT_ID??$?.clientId,signature:process.env.ES_LFV_SIGNATURE??$?.signature,deliveryEndpoint:process.env.ES_LFV_DELIVERY_ENDPOINT??$?.deliveryEndpoint,verifyPublicKey:process.env.ES_LFV_VERIFY_PUBLIC_KEY??$?.verifyPublicKey,eventsEndpoint:process.env.ES_LFV_EVENTS_ENDPOINT??$?.eventsEndpoint,deliveryTimeout:WS(process.env.ES_LFV_DELIVERY_TIMEOUT)??$?.deliveryTimeout,retryInterval:WS(process.env.ES_LFV_RETRY_INTERVAL)??$?.retryInterval,warnInterval:WS(process.env.ES_LFV_WARN_INTERVAL)??$?.warnInterval})}else if(L==="localFile"){let $=S??{};return IS({path:process.env.ES_FILE_PATH??$?.path,watch:process.env.ES_FILE_WATCH==="true"||$?.watch,ttl:process.env.ES_FILE_TTL?parseInt(process.env.ES_FILE_TTL,10):void 0})}else if(L==="vault"){let $=S??{};return $.vault?NS($):NS({url:process.env.ES_VAULT_URL??$?.url,token:process.env.ES_VAULT_TOKEN??$?.token,path:process.env.ES_VAULT_PATH??$?.path,ttl:process.env.ES_VAULT_TTL?parseInt(process.env.ES_VAULT_TTL,10):void 0})}else if(L==="azure"){let $=S??{};return $.vault?GS($):GS({apiVersion:process.env.ES_AZURE_API_VERSION??$?.apiVersion,scope:process.env.ES_AZURE_SCOPE??$?.scope,secretNamePrefix:process.env.ES_AZURE_SECRET_NAME_PREFIX??$?.secretNamePrefix,authMethod:process.env.ES_AZURE_AUTH_METHOD??$?.authMethod,tenantId:process.env.ES_AZURE_TENANT_ID??$?.tenantId,clientId:process.env.ES_AZURE_CLIENT_ID??$?.clientId,clientSecret:process.env.ES_AZURE_CLIENT_SECRET??$?.clientSecret,federatedTokenFile:process.env.ES_AZURE_FEDERATED_TOKEN_FILE??$?.federatedTokenFile,managedIdentityClientId:process.env.ES_AZURE_MANAGED_IDENTITY_CLIENT_ID??$?.managedIdentityClientId,imdsApiVersion:process.env.ES_AZURE_IMDS_API_VERSION??$?.imdsApiVersion,vaultUrl:process.env.ES_AZURE_VAULT_URL??$?.vaultUrl,vaultName:process.env.ES_AZURE_VAULT_NAME??$?.vaultName,ttl:process.env.ES_AZURE_TTL?parseInt(process.env.ES_AZURE_TTL,10):void 0})}else if(L==="aws"){let $=S??{};return $.vault?ZS($):ZS({webhookUrl:process.env.ES_AWS_WEBHOOK_URL??$?.webhookUrl,ttl:process.env.ES_AWS_TTL?parseInt(process.env.ES_AWS_TTL,10):void 0})}else if(L==="gcp"){let $=S??{};return $.vault?MS($):MS({ttl:process.env.ES_GCP_TTL?parseInt(process.env.ES_GCP_TTL,10):void 0})}throw Error(`ES_CONFIG_TYPE="${L}" is not a valid ConfigSourceType when using envConfig().`)}import{defaultLogger as JL}from"@enterprisestandard/core";import{list as NL}from"@enterprisestandard/core";class ES{groups=new Map;externalIdIndex=new Map;displayNameIndex=new Map;async get(S){return this.groups.get(S)??null}async getByExternalId(S){let L=this.externalIdIndex.get(S);if(!L)return null;return this.groups.get(L)??null}async getByDisplayName(S){let L=this.displayNameIndex.get(S.toLowerCase());if(!L)return null;return this.groups.get(L)??null}async list(S){let L=Array.from(this.groups.values()),$=Math.max(0,S?.start??0),R=S?.limit;if(S?.sort?.length)L=[...L].sort((F,z)=>{for(let{field:Z,direction:Q}of S.sort){let K=F[Z],T=z[Z],y=EL(K,T);if(y!==0)return Q==="desc"?-y:y}return 0});let U=L.length,D=R!=null?$+R:void 0,X=L.slice($,D);return NL(U,X,$,R)}async upsert(S){let L=this.groups.get(S.id);if(L){if(L.externalId&&L.externalId!==S.externalId)this.externalIdIndex.delete(L.externalId);if(L.displayName.toLowerCase()!==S.displayName.toLowerCase())this.displayNameIndex.delete(L.displayName.toLowerCase())}if(this.groups.set(S.id,S),S.externalId)this.externalIdIndex.set(S.externalId,S.id);this.displayNameIndex.set(S.displayName.toLowerCase(),S.id)}async delete(S){let L=this.groups.get(S);if(L){if(L.externalId)this.externalIdIndex.delete(L.externalId);this.displayNameIndex.delete(L.displayName.toLowerCase())}this.groups.delete(S)}async addMember(S,L){let $=this.groups.get(S);if(!$)throw Error(`Group ${S} not found`);let R=$.members??[];if(!R.some((U)=>U.value===L.value))R.push(L),$.members=R,$.updatedAt=new Date}async removeMember(S,L){let $=this.groups.get(S);if(!$)throw Error(`Group ${S} not found`);if($.members)$.members=$.members.filter((R)=>R.value!==L),$.updatedAt=new Date}}function EL(S,L){let $=S===void 0||S===null,R=L===void 0||L===null;if($&&R)return 0;if($)return 1;if(R)return-1;if(S instanceof Date&&L instanceof Date)return S.getTime()-L.getTime();let U=String(S),D=String(L);return U.localeCompare(D)}class KS{magicLinks=new Map;async create(S,L,$){if(this.magicLinks.has(S))throw Error(`Magic link with token ${S} already exists`);let R={token:S,user:L,createdAt:new Date,expiresAt:$};this.magicLinks.set(S,R)}async get(S){let L=this.magicLinks.get(S);if(!L)return null;if(Date.now()>L.expiresAt.getTime())return this.magicLinks.delete(S),null;return L}async delete(S){this.magicLinks.delete(S)}}class HS{sessions=new Map;async create(S){if(this.sessions.has(S.sid))throw Error(`Session with sid ${S.sid} already exists`);this.sessions.set(S.sid,S)}async get(S){return this.sessions.get(S)??null}async update(S,L){let $=this.sessions.get(S);if(!$)throw Error(`Session with sid ${S} not found`);let R={...$,...L};this.sessions.set(S,R)}async delete(S){this.sessions.delete(S)}}import{list as KL}from"@enterprisestandard/core";class JS{users=new Map;emailIndex=new Map;userNameIndex=new Map;async get(S){return this.users.get(S)??null}async getByEmail(S){let L=this.emailIndex.get(S.toLowerCase());if(!L)return null;return this.users.get(L)??null}async getByUserName(S){let L=this.userNameIndex.get(S.toLowerCase());if(!L)return null;return this.users.get(L)??null}async upsert(S){let L=this.users.get(S.id);if(L){if(L.email&&L.email.toLowerCase()!==S.email?.toLowerCase())this.emailIndex.delete(L.email.toLowerCase());if(L.userName&&L.userName.toLowerCase()!==S.userName?.toLowerCase())this.userNameIndex.delete(L.userName.toLowerCase())}if(this.users.set(S.id,S),S.email)this.emailIndex.set(S.email.toLowerCase(),S.id);if(S.userName)this.userNameIndex.set(S.userName.toLowerCase(),S.id)}async delete(S){let L=this.users.get(S);if(L){if(L.email)this.emailIndex.delete(L.email.toLowerCase());if(L.userName)this.userNameIndex.delete(L.userName.toLowerCase())}this.users.delete(S)}async list(S){let L=Array.from(this.users.values()),$=Math.max(0,S?.start??0),R=S?.limit;if(S?.sort?.length)L=[...L].sort((F,z)=>{for(let{field:Z,direction:Q}of S.sort){let K=F[Z],T=z[Z],y=HL(K,T);if(y!==0)return Q==="desc"?-y:y}return 0});let U=L.length,D=R!=null?$+R:void 0,X=L.slice($,D);return KL(U,X,$,R)}}function HL(S,L){let $=S===void 0||S===null,R=L===void 0||L===null;if($&&R)return 0;if($)return 1;if(R)return-1;if(S instanceof Date&&L instanceof Date)return S.getTime()-L.getTime();return String(S).localeCompare(String(L))}class $S{tokens=new Map;async set(S){this.tokens.set(S.workload_id,S)}async get(S){let L=this.tokens.get(S);if(!L)return null;if(Date.now()>L.expires_at.getTime())return this.tokens.delete(S),null;return L}async delete(S){this.tokens.delete(S)}async isValid(S){return await this.get(S)!==null}async cleanup(){let S=Date.now();for(let[L,$]of this.tokens.entries())if(S>$.expires_at.getTime())this.tokens.delete(L)}}var wS="__esDynamicConfig";function BS(S){if(!S)return;try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}function BL(S){let L=S.workload;if(!L||typeof L!=="object")return;if(typeof L.tokenUrl==="string")return BS(L.tokenUrl);let $=L.incoming;if($&&typeof $.tokenUrl==="string")return BS($.tokenUrl);let R=L.default;if(R&&typeof R.tokenUrl==="string")return BS(R.tokenUrl);return}function FL(S,L,$){let R={...L},U=$.basePath,D=$.stores;if($.validators&&!R.validators)R.validators=$.validators;if($.logger&&!R.logger)R.logger=$.logger;if(S.sso&&!R.sso)R.sso={redirectUri:BS(S.sso.redirectUri)??`${U}/auth/callback`,loginUrl:`${U}/auth/login`,userUrl:`${U}/auth/user`,logoutUrl:`${U}/auth/logout`,logoutBackChannelUrl:`${U}/auth/logout/backchannel`,sessionStore:D.sessionStore,userStore:D.userStore,enableJitUserProvisioning:!0};if(S.iam&&!R.iam)R.iam={usersUrl:`${U}/iam/Users`,groupsUrl:`${U}/iam/Groups`,userStore:D.userStore,groupStore:D.groupStore};if(S.workload&&!R.workload)R.workload={tokenUrl:BL(S)??`${U}/workload/token`,validateUrl:`${U}/workload/validate`,jwksUrl:`${U}/workload/jwks`,refreshUrl:`${U}/workload/refresh`,tokenStore:D.workloadTokenStore};if(S.ciam&&!R.ciam)R.ciam={magicLinkUrl:`${U}/magic-link`,magicLinkLoginUrl:`${U}/magic-link/login`,logoutUrl:`${U}/auth/logout`,logoutBackChannelUrl:`${U}/auth/logout/backchannel`,landingUrl:"/",sessionStore:D.sessionStore,userStore:D.userStore,magicLinkStore:D.magicLinkStore,enableJitUserProvisioning:!0};if(S.tenant&&!R.tenant)R.tenant={};return R}function qL(S,L){return($,R,U)=>{let D=FL($,R,L),X=S?.($,D,U);return{config:X?.config??$,frameworkConfig:X?.frameworkConfig??D}}}function jL(S={}){return{validators:S.validators,logger:S.logger,stores:{sessionStore:S.stores?.sessionStore??new HS,userStore:S.stores?.userStore??new JS,groupStore:S.stores?.groupStore??new ES,magicLinkStore:S.stores?.magicLinkStore??new KS,workloadTokenStore:S.stores?.workloadTokenStore??new $S},basePath:S.basePath??"/api/es"}}function FS(S={}){let L=jL(S);return{validators:L.validators,logger:L.logger,[wS]:L}}function TL(S={}){return FS(S)}function lS(S,L){let $=S??{},R=$[wS];if(!R)return{config:S??{},options:L};let U={...$};delete U[wS];let D={...L??{},beforeChange:qL(L?.beforeChange,R)};return(U.logger??JL).info?.("Dynamic framework configuration enabled",{basePath:R.basePath,adaptiveStores:!0}),{config:U,options:D}}import{logout as iS,logoutBackChannel as pS}from"@enterprisestandard/core/server";function tS(S){if(!S)return;try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}function rS(S){return S==="/"?S:S.replace(/\/+$/,"")}function AL(S){let L=rS(S);return{matchesPath:(U)=>{if(!U)return!1;let D=tS(U);if(!D)return!1;return rS(D)===L},startsWithPath:(U)=>{if(!U)return!1;let D=tS(U);if(!D)return!1;return S===D||S.startsWith(`${D}/`)}}}function PL(S,L){let $=new URL(S.url).pathname,{matchesPath:R,startsWithPath:U}=AL($);if(L.sso){let D=L.sso;if(R(L.sso.userUrl))return{module:"sso",kind:"sso.user",handler:async(X)=>{let F=await D.handler(X);if(F.status===401&&L.ciam){let z=await L.ciam.getUser(X);if(z)return new Response(JSON.stringify(z),{headers:{"Content-Type":"application/json"}})}return F}};if(R(L.sso.logoutUrl))return{module:"sso",kind:"sso.logout",handler:async(X)=>iS(X,L)};if(R(L.sso.logoutBackChannelUrl))return{module:"sso",kind:"sso.logout_backchannel",handler:async(X)=>pS(X,L)};if(R(L.sso.loginUrl)||R(L.sso.tokenUrl)||R(L.sso.refreshUrl)||R(L.sso.jwksUrl)||R(L.sso.redirectUri))return{module:"sso",kind:"sso.handler",handler:async(X)=>D.handler(X)}}if(L.ciam){if(R(L.ciam.logoutUrl))return{module:"ciam",kind:"ciam.logout",handler:async(D)=>iS(D,L)};if(R(L.ciam.logoutBackChannelUrl))return{module:"ciam",kind:"ciam.logout_backchannel",handler:async(D)=>pS(D,L)}}if(L.iam){let D=L.iam;if(U(L.iam.usersUrl)||U(L.iam.groupsUrl))return{module:"iam",kind:"iam.handler",handler:async(X)=>D.handler(X)}}if(L.workload){let D=L.workload,z=D._handlerTokenUrl??(D.tokenUrl?.startsWith("/")?D.tokenUrl:void 0)??(D.tokenUrl&&!D.tokenUrl.startsWith("http")?D.tokenUrl:void 0),Z="validateUrl"in D?D.validateUrl:void 0,Q="jwksUrl"in D?D.jwksUrl:void 0,K="refreshUrl"in D?D.refreshUrl:void 0;if(R(z)||R(Z)||R(Q)||R(K))return{module:"workload",kind:"workload.handler",handler:async(T)=>D.handler(T)}}if(L.secrets){let D=L.secrets;if(D.isLfvDeliveryRequest?.(S)&&D.handleLfvDelivery){let X=D.handleLfvDelivery;return{module:"secrets",kind:"secrets.lfv_delivery",handler:async(F)=>X(F)}}if(D.isLfvEventsRequest?.(S)&&D.handleLfvEvents){let X=D.handleLfvEvents;return{module:"secrets",kind:"secrets.lfv_events",handler:async(F)=>X(F)}}}if(L.ciam){let D=L.ciam,X=L.ciam.magicLinkUrl||"/magic-link",F=L.ciam.magicLinkLoginUrl||"/magic-link/login";if(R(X)&&S.method==="POST"||R(F)&&S.method==="GET")return{module:"ciam",kind:"ciam.handler",handler:async(z)=>D.handler(z)}}return}async function aS(S,L,$){if($?.filter){let X=await $.filter(S,L);if(X instanceof Response)return X;if(X==="not_handled")return new Response("Not Found",{status:404})}let R=()=>PL(S,L),U=await $?.resolve?.(S,L,R)??R();if(!U)return new Response("Not Found",{status:404});let D=async()=>U.handler(S);if($?.wrap)return await $.wrap(S,U,D,L);return await D()}import{readFile as VL,stat as OL}from"node:fs/promises";function qS(S,L){if(!S||S.trim().length===0)throw Error(`Missing required Azure config: ${L}`);return S}function IL(S){return S.replace(/^\/+|\/+$/g,"").replaceAll("/","--")}function yS(S,L){return`${S.replace(/\/+$/g,"")}/${L.replace(/^\/+/g,"")}`}function WL(S){try{let $=new URL(S).pathname.split("/").filter(Boolean),R=$.indexOf("secrets");if(R===-1)return;return $[R+2]||void 0}catch{return}}function xL(S){return typeof S==="object"&&S!==null&&!Array.isArray(S)}function eS(S){let L=S.apiVersion??"7.4",$=S.scope??"https://vault.azure.net/.default",R=S.secretNameTransform??IL,U=S.authMethod,D="/var/run/secrets/azure/tokens/azure-identity-token",X=S.federatedTokenFile??"/var/run/secrets/azure/tokens/azure-identity-token",F=S.vaultUrl??(S.vaultName?`https://${S.vaultName}.vault.azure.net`:void 0)??void 0,z=qS(F,"vaultUrl or vaultName (ES_AZURE_KEY_VAULT_URL / ES_AZURE_KEY_VAULT_NAME)");async function Z(P){try{return await OL(P),!0}catch{return!1}}let Q,K;async function T(P){let{tenantId:u,clientId:x}=S;if(!u)throw Error("Workload identity requires tenantId");if(!x)throw Error("Workload identity requires clientId");if(!await Z(X))throw Error(`Federated token file not found at ${X}`);let v=(await VL(X,"utf8")).trim();if(!v)throw Error("Federated token file was empty");let b=`https://login.microsoftonline.com/${encodeURIComponent(u)}/oauth2/v2.0/token`,h=new URLSearchParams({client_id:x,grant_type:"client_credentials",scope:$,client_assertion_type:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",client_assertion:v}),I=await fetch(b,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:h});if(I.status!==200){let M=await I.text().catch(()=>"");throw Error(`Azure workload identity token exchange returned ${I.status} ${I.statusText}. tenantId=${u}. Response: ${M}`)}let m=await I.json();if(!m?.access_token)throw Error("Azure token response missing access_token");return Q={accessToken:m.access_token,expiresAtMs:P+(m.expires_in??0)*1000},m.access_token}async function y(P){let u=S.imdsApiVersion??"2018-02-01",x="https://vault.azure.net",v=new URL("http://169.254.169.254/metadata/identity/oauth2/token");if(v.searchParams.set("api-version",u),v.searchParams.set("resource","https://vault.azure.net"),S.managedIdentityClientId)v.searchParams.set("client_id",S.managedIdentityClientId);let b=await fetch(v.toString(),{headers:{Metadata:"true",Accept:"application/json"}});if(b.status!==200){let m=await b.text().catch(()=>"");throw Error(`Azure IMDS token endpoint returned ${b.status} ${b.statusText}. Response: ${m}`)}let h=await b.json();if(!h?.access_token)throw Error("IMDS token response missing access_token");let I=P+60000;if(h.expires_on){let m=Number.parseInt(h.expires_on,10);if(Number.isFinite(m)&&m>0)I=m*1000;else{let M=Date.parse(h.expires_on);if(Number.isFinite(M))I=M}}else if(h.expires_in){let m=Number.parseInt(h.expires_in,10);if(Number.isFinite(m)&&m>0)I=P+m*1000}return Q={accessToken:h.access_token,expiresAtMs:I},h.access_token}async function d(P){let u=qS(S.tenantId,"tenantId (or ES_AZURE_TENANT_ID/AZURE_TENANT_ID)"),x=qS(S.clientId,"clientId (or ES_AZURE_CLIENT_ID/AZURE_CLIENT_ID)"),v=qS(S.clientSecret,"clientSecret (or ES_AZURE_CLIENT_SECRET)"),b=`https://login.microsoftonline.com/${encodeURIComponent(u)}/oauth2/v2.0/token`,h=new URLSearchParams({client_id:x,client_secret:v,grant_type:"client_credentials",scope:$}),I=await fetch(b,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:h});if(I.status!==200){let M=await I.text().catch(()=>"");throw Error(`Azure token endpoint returned ${I.status} ${I.statusText}. tenantId=${u}. Response: ${M}`)}let m=await I.json();if(!m?.access_token)throw Error("Azure token response missing access_token");return Q={accessToken:m.access_token,expiresAtMs:P+(m.expires_in??0)*1000},m.access_token}async function H(){let P=Date.now();if(Q&&Q.expiresAtMs-60000>P)return Q.accessToken;if(K)return K;K=(async()=>{if(U==="workload_identity")return await T(P);if(U==="managed_identity")return await y(P);if(U==="client_secret")return await d(P);if(await Z(X))try{return await T(P)}catch{}try{return await y(P)}catch{}return await d(P)})();try{return await K}finally{K=void 0}}async function O(P){let u=await H(),x=yS(z,`/secrets/${encodeURIComponent(P)}?api-version=${encodeURIComponent(L)}`),v=await fetch(x,{headers:{Authorization:`Bearer ${u}`,Accept:"application/json"}});if(v.status!==200){let b=await v.text().catch(()=>"");throw Error(`Key Vault returned ${v.status} ${v.statusText} for ${x}. Response: ${b}`)}return await v.json()}async function q(P,u){let x=R(P),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await O(v),h=b.value;try{h=JSON.parse(b.value)}catch{}let I=b.attributes?.created?b.attributes.created*1000:void 0,m=WL(b.id);return{data:h,metadata:{path:P,version:Number.parseInt(m??"",10)||0,created:I?new Date(I):new Date}}}async function V(P,u,x){if(!xL(u))throw Error(`putSecret requires an object value for azure source at path ${P}`);let v=R(P),b=S.secretNamePrefix?`${S.secretNamePrefix}${v}`:v,h=await H(),I=yS(z,`/secrets/${encodeURIComponent(b)}?api-version=${encodeURIComponent(L)}`),m=JSON.stringify({value:JSON.stringify(u)}),M=await fetch(I,{method:"PUT",headers:{Authorization:`Bearer ${h}`,"Content-Type":"application/json",Accept:"application/json"},body:m});if(M.status!==200&&M.status!==201){let G=await M.text().catch(()=>"");throw Error(`Key Vault putSecret returned ${M.status} for ${I}: ${G}`)}}async function k(P,u){let x=R(P),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await H(),h=yS(z,`/secrets/${encodeURIComponent(v)}?api-version=${encodeURIComponent(L)}`),I=await fetch(h,{method:"DELETE",headers:{Authorization:`Bearer ${b}`,Accept:"application/json"}});if(I.status!==200&&I.status!==202&&I.status!==204){let m=await I.text().catch(()=>"");throw Error(`Key Vault deleteSecret returned ${I.status} for ${h}: ${m}`)}}async function g(P,u){throw Error(`listPaths is not implemented for Azure Key Vault source at path ${P}`)}async function t(P,u){try{return await q(P),!0}catch(x){if((x instanceof Error?x.message:String(x)).includes(" 404 "))return!1;throw x}}async function s(P,u,x){throw Error(`requestRotate is not implemented for Azure Key Vault source at path ${P}`)}async function i(P,u,x){throw Error(`requestRevoke is not implemented for Azure Key Vault source at path ${P}`)}async function US(P,u){let x=R(P),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await O(v);return{id:b.id,...b.attributes??{}}}return{type:S.type,getFullSecret:q,getSecret:async(P,u)=>{return(await q(P,u)).data},putSecret:V,deleteSecret:k,listPaths:g,exists:t,requestRotate:s,requestRevoke:i,getMetadata:US,subscribe:(P,u)=>{throw Error("TODO: subscribe not implemented for azure vault")}}}function oS(S){async function L(Z,Q){throw Error("Error retrieving secret",{cause:Error("Not implemented")})}async function $(Z,Q,K){throw Error("putSecret not implemented for dev vault")}async function R(Z,Q){throw Error(`deleteSecret not implemented for dev vault at path ${Z}`)}async function U(Z,Q){throw Error(`listPaths not implemented for dev vault at path ${Z}`)}async function D(Z,Q){throw Error(`exists not implemented for dev vault at path ${Z}`)}async function X(Z,Q,K){throw Error(`requestRotate not implemented for dev vault at path ${Z}`)}async function F(Z,Q,K){throw Error(`requestRevoke not implemented for dev vault at path ${Z}`)}async function z(Z,Q){throw Error(`getMetadata not implemented for dev vault at path ${Z}`)}return{type:S.type,getFullSecret:L,getSecret:async(Z,Q)=>{return(await L(Z,Q)).data},putSecret:$,deleteSecret:R,listPaths:U,exists:D,requestRotate:X,requestRevoke:F,getMetadata:z,subscribe:(Z,Q)=>{throw Error("TODO: subscribe not implemented for dev vault")}}}function SL(S,L){let $=(R,U)=>{throw Error(`${R} is not implemented for source "${L}" (type: ${S}) at path ${U}`)};return{type:S,getFullSecret:(R,U)=>Promise.reject($("getFullSecret",R)),getSecret:(R,U)=>Promise.reject($("getSecret",R)),putSecret:(R,U,D)=>Promise.reject($("putSecret",R)),subscribe:(R,U)=>{return $("subscribe",R),()=>{}},deleteSecret:(R,U)=>Promise.reject($("deleteSecret",R)),listPaths:(R,U)=>Promise.reject($("listPaths",R)),exists:(R,U)=>Promise.reject($("exists",R)),requestRotate:(R,U,D)=>Promise.reject($("requestRotate",R)),requestRevoke:(R,U,D)=>Promise.reject($("requestRevoke",R)),getMetadata:(R,U)=>Promise.reject($("getMetadata",R))}}function wL(S,L){if(L.type==="vault")return _S(L);if(L.type==="lfv")return zS(L);if(L.type==="azure")return eS(L);if(L.type==="dev")return oS(L);if(L.type==="aws")return SL(L.type,S);if(L.type==="gcp")return SL(L.type,S);throw Error(`Unsupported secrets source type for "${S}"`)}function yL(S){return S.type==="lfv"&&typeof S.isDeliveryRequest==="function"&&typeof S.isEventsRequest==="function"&&typeof S.handleDelivery==="function"&&typeof S.handleEvents==="function"}function kL(S,L){let $={},R=new Set([...Object.keys(S??{}),...Object.keys(L??{})]);for(let U of R){let D=S?.[U],X=L?.[U];$[U]={...D??{},...X??{}}}return $}function kS(S,L,$,R){if(!$&&!R)return;let U=kL($,R),D={};for(let[Q,K]of Object.entries(U))S?.validateSourceConfig?.(Q,K),D[Q]=wL(Q,K);let X=(Q)=>{let K=D[Q];if(!K)throw L.warn?.(`Secrets source "${Q}" is not configured`),Error(`Secrets source "${Q}" is not configured`);return K},F=()=>{return Object.values(D).filter(yL)},z=(Q)=>{return F().find((K)=>K.isDeliveryRequest(Q))},Z=(Q)=>{return F().find((K)=>K.isEventsRequest(Q))};return{config:D,listSecretsSources:()=>Object.keys(D),getSecretsSource:X,getSecret:(Q,K,T)=>X(Q).getSecret(K,T),getFullSecret:(Q,K,T)=>X(Q).getFullSecret(K,T),putSecret:(Q,K,T,y)=>X(Q).putSecret(K,T,y),deleteSecret:(Q,K,T)=>X(Q).deleteSecret(K,T),listPaths:(Q,K,T)=>X(Q).listPaths(K,T),exists:(Q,K,T)=>X(Q).exists(K,T),requestRotate:(Q,K,T,y)=>X(Q).requestRotate(K,T,y),requestRevoke:(Q,K,T,y)=>X(Q).requestRevoke(K,T,y),getMetadata:(Q,K,T)=>X(Q).getMetadata(K,T),subscribe:(Q,K,T)=>X(Q).subscribe(K,T),isLfvDeliveryRequest:(Q)=>z(Q)!==void 0,isLfvEventsRequest:(Q)=>Z(Q)!==void 0,handleLfvDelivery:async(Q)=>{let K=z(Q);if(!K)return new Response("Not Found",{status:404});return K.handleDelivery(Q)},handleLfvEvents:async(Q)=>{let K=Z(Q);if(!K)return new Response("Not Found",{status:404});return K.handleEvents(Q)}}}import{must as r}from"@enterprisestandard/core";var LL=new Map;function l(S){if(S===void 0||S===null)return!1;let L=S;return L.workloadId!==void 0&&L.workloadId!==null||L.privateKey!==void 0&&L.privateKey!==null}function o(S){if(S===void 0||S===null)return!1;let L=S,$=L.clientId!==void 0&&L.clientId!==null,R=L.clientSecret!==void 0&&L.clientSecret!==null,U=L.workloadId!==void 0&&L.workloadId!==null,D=L.privateKey!==void 0&&L.privateKey!==null;return($||R)&&!U&&!D}function vS(S){if(S===void 0||S===null)return!1;let L=S,$=L.jwksUri!==void 0&&L.jwksUri!==null,R=L.workloadId!==void 0&&L.workloadId!==null,U=L.clientId!==void 0&&L.clientId!==null,D=L.clientSecret!==void 0&&L.clientSecret!==null,X=L.privateKey!==void 0&&L.privateKey!==null;return $&&!R&&!X&&!U&&!D}function $L(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;return"clientId"in L||"jwksUri"in L||"workloadId"in L}function vL(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;if($L(L))return!1;let $=Object.entries(L);if($.length===0)return!1;return $.every(([,R])=>$L(R))}function bL(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;if("incoming"in L||"outgoing"in L){if(L.incoming!==void 0&&(typeof L.incoming!=="object"||L.incoming===null))return!1;if(L.outgoing!==void 0&&(typeof L.outgoing!=="object"||L.outgoing===null||Array.isArray(L.outgoing)))return!1;return!0}return!1}function RS(S,L,$,R){if(!$&&!R)return;if($&&bL($)){let M=$.incoming,G=M?{...M,...R,jwksUri:M.jwksUri,issuer:M.issuer}:R;if(!G||!G.tokenUrl&&!G.jwksUri)L.warn("Workload vault config has incoming/outgoing but no server config (incoming or framework) with tokenUrl/jwksUri; workload module handler will be unavailable.");let N=G&&(G.tokenUrl||G.jwksUri)?RS(S,L,M??void 0,R):void 0,j=Object.entries($.outgoing??{}),J={};for(let[E,_]of j){let Y=RS(S,L,_,void 0);if(Y)J[E]=Y}if(!N&&Object.keys(J).length===0)return;return{...N?.config??{},getToken:async(E,_)=>{if(_?.client){let B=J[_.client];if(!B)throw Error(`Unknown workload client: ${_.client}`);return B.getToken(E)}if(N)return N.getToken(E);let Y=Object.keys(J);if(Y.length>1)throw Error(`Multiple named clients are configured, but no client was specified. Available clients: ${Y.join(", ")}`);if(Y.length===1)return J[Y[0]].getToken(E);throw Error("No workload config available; specify options.client")},refreshToken:async(E)=>{if(!N)throw Error("No default workload config");return N.refreshToken(E)},generateJWTAssertion:async(E)=>{if(!N)throw Error("No default workload config");return N.generateJWTAssertion(E)},revokeToken:async(E)=>{if(!N)throw Error("No default workload config");return N.revokeToken(E)},validateToken:async(E)=>{if(!N)throw Error("No default workload config");return N.validateToken(E)},getWorkloadIdentity:async(E)=>{if(!N)return;return N.getWorkloadIdentity(E)},parseJWT:async(E)=>{if(!N)throw Error("No default workload config");return N.parseJWT(E)},handler:async(E)=>{if(!N)return new Response("Not Found",{status:404});return N.handler(E)}}}if($&&vL($)){let M=$.default,G=M?{...M,...R,jwksUri:M.jwksUri,issuer:M.issuer}:R;if(!G||!G.tokenUrl&&!G.jwksUri)L.warn('Workload vault config is a clients map but no server config (workload["default"] or framework workload) with tokenUrl/jwksUri; workload module handler will be unavailable.');let N=G&&(G.tokenUrl||G.jwksUri)?RS(S,L,M??void 0,R):void 0,j=Object.entries($).filter(([E])=>E!=="default"),J={};for(let[E,_]of j){let Y=RS(S,L,_,void 0);if(Y)J[E]=Y}if(!N&&Object.keys(J).length===0)return;return{...N?.config??{},getToken:async(E,_)=>{if(_?.client){let B=J[_.client];if(!B)throw Error(`Unknown workload client: ${_.client}`);return B.getToken(E)}if(N)return N.getToken(E);let Y=Object.keys(J);if(Y.length>1)throw Error(`Multiple named clients are configured, but no client was specified. Available clients: ${Y.join(", ")}`);if(Y.length===1)return J[Y[0]].getToken(E);throw Error("No workload config available; specify options.client")},refreshToken:async(E)=>{if(!N)throw Error("No default workload config");return N.refreshToken(E)},generateJWTAssertion:async(E)=>{if(!N)throw Error("No default workload config");return N.generateJWTAssertion(E)},revokeToken:async(E)=>{if(!N)throw Error("No default workload config");return N.revokeToken(E)},validateToken:async(E)=>{if(!N)throw Error("No default workload config");return N.validateToken(E)},getWorkloadIdentity:async(E)=>{if(!N)return;return N.getWorkloadIdentity(E)},parseJWT:async(E)=>{if(!N)throw Error("No default workload config");return N.parseJWT(E)},handler:async(E)=>{if(!N)return new Response("Not Found",{status:404});return N.handler(E)}}}let U=$,D=R?.tokenUrl,X=D?.startsWith("/")?D:void 0,F=U?.idpTokenUrl??R?.idpTokenUrl??(U?.tokenUrl&&(U.tokenUrl.startsWith("http://")||U.tokenUrl.startsWith("https://"))?U.tokenUrl:void 0),z={...U,...R,tokenUrl:X??R?.tokenUrl??U?.tokenUrl,idpTokenUrl:F,jwksUri:U?.jwksUri,issuer:U?.issuer};z._handlerTokenUrl=X;let Z,Q=z,K=l(z),T=o(z),y=vS(z);if(!K&&!T&&!y){if(!U||Object.keys(U).length===0)return;throw L.error("WorkloadConfig validation failed. Config:",{keys:Object.keys(z),clientId:Q.clientId,clientSecret:Q.clientSecret?"[REDACTED]":void 0,workloadId:Q.workloadId,privateKey:Q.privateKey?"[REDACTED]":void 0,jwksUri:Q.jwksUri,tokenUrl:Q.tokenUrl,idpTokenUrl:Q.idpTokenUrl,fromVaultKeys:U?Object.keys(U):[],fromCodeKeys:R?Object.keys(R):[]}),Error("Invalid WorkloadConfig: must provide the correct config for one of the following modes: JWT Bearer Grant, OAuth2 Client Credentials, or Server-Only")}if(K)Z={...z,tokenUrl:z.tokenUrl,idpTokenUrl:r(z.idpTokenUrl,"Missing 'idpTokenUrl' from Workload Config"),workloadId:r(z.workloadId,"Missing 'workloadId' from Workload Config"),privateKey:r(z.privateKey,"Missing 'privateKey' from Workload Config"),audience:r(z.audience,"Missing 'audience' from Workload Config"),scope:z.scope??"",algorithm:z.algorithm??"RS256",tokenLifetime:z.tokenLifetime??300,refreshThreshold:z.refreshThreshold??60,autoRefresh:z.autoRefresh!==void 0?z.autoRefresh:!0,tokenStore:z.tokenStore??new $S};else if(o(z))Z={...z,tokenUrl:z.tokenUrl,idpTokenUrl:r(z.idpTokenUrl,"Missing 'idpTokenUrl' from Workload Config"),clientId:r(z.clientId,"Missing 'clientId' from Workload Config"),clientSecret:r(z.clientSecret,"Missing 'clientSecret' from Workload Config"),scope:z.scope??"",tokenLifetime:z.tokenLifetime??300,refreshThreshold:z.refreshThreshold??60,autoRefresh:z.autoRefresh!==void 0?z.autoRefresh:!0,tokenStore:z.tokenStore??new $S};else if(vS(z))Z=z;function d(){let M=new Uint8Array(16);return crypto.getRandomValues(M),Array.from(M,(G)=>G.toString(16).padStart(2,"0")).join("")}function H(M){let G;if(typeof M==="string")G=btoa(M);else G=btoa(String.fromCharCode(...M));return G.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function O(M){let G=M.replace(/-/g,"+").replace(/_/g,"/");while(G.length%4)G+="=";return atob(G)}function q(M){if(M.startsWith("RS"))return{name:"RSASSA-PKCS1-v1_5",hash:M==="RS256"?"SHA-256":M==="RS384"?"SHA-384":"SHA-512"};else if(M.startsWith("ES"))return{name:"ECDSA",namedCurve:M==="ES256"?"P-256":M==="ES384"?"P-384":"P-521",hash:M==="ES256"?"SHA-256":M==="ES384"?"SHA-384":"SHA-512"};throw Error(`Unsupported algorithm: ${M}`)}async function V(M,G){let N=M.replace(/-----BEGIN PRIVATE KEY-----/,"").replace(/-----END PRIVATE KEY-----/,"").replace(/\s/g,""),j=Uint8Array.from(atob(N),(W)=>W.charCodeAt(0)),J=q(G);return crypto.subtle.importKey("pkcs8",j,J,!1,["sign"])}async function k(M,G,N){let j=await V(G,N),W=new TextEncoder().encode(M),E=q(N),_=await crypto.subtle.sign(E,j,W);return H(new Uint8Array(_))}async function g(M,G=3,N=1000,j=30000){let J=Error("Placeholder Error");for(let W=0;W<=G;W++)try{return await M()}catch(E){if(J=E instanceof Error?E:Error(String(E)),J.message.includes("400")||J.message.includes("401")||J.message.includes("403")||J.message.includes("404"))throw J;if(W<G){let _=Math.min(N*2**W,j),Y=Math.random()*_*0.1;await new Promise((B)=>setTimeout(B,_+Y))}}throw J}async function t(M){if(!l(Z))throw Error("generateJWTAssertion is only available in JWT Bearer Grant mode");let G=Z,N=Math.floor(Date.now()/1000),j={iss:G.workloadId,sub:G.workloadId,aud:G.audience??"",exp:N+G.tokenLifetime,iat:N,jti:d(),scope:M??G.scope},J={alg:G.algorithm,typ:"JWT",kid:G.keyId},W=H(JSON.stringify(J)),E=H(JSON.stringify(j)),_=`${W}.${E}`,Y=await k(_,G.privateKey,G.algorithm);return`${_}.${Y}`}async function s(M){if(!l(Z))throw Error("generateJWTAssertion is only available in JWT Bearer Grant mode");let G=Z;return g(async()=>{let N=G.idpTokenUrl,j=await t(M),J=new URLSearchParams;if(J.append("grant_type","urn:ietf:params:oauth:grant-type:jwt-bearer"),J.append("assertion",j),M)J.append("scope",M);let W=await fetch(N,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()}),E=await W.json();if(!W.ok)throw L.error("Token acquisition error:",E),Error(`Token acquisition failed: ${E.error||W.statusText} - ${E.error_description||""}`.trim());let _=await S.tokenResponse["~standard"].validate(E);if(_.issues)throw L.error("Token response validation failed:",_.issues),Error(`Token response validation failed: ${_.issues.map((Y)=>Y.message).join("; ")}`);if(G.tokenStore){let Y=new Date(Date.now()+(_.value.expires_in??300)*1000),B={workload_id:G.workloadId,access_token:_.value.access_token,token_type:_.value.token_type,scope:_.value.scope,expires_at:Y,created_at:new Date,refresh_token:_.value.refresh_token};await G.tokenStore.set(B)}return _.value})}async function i(M){if(!o(Z))throw Error("acquireTokenClientCredentials is only available in OAuth2 Client Credentials mode");let G=Z;return g(async()=>{let N=G.idpTokenUrl,j=new URLSearchParams;if(j.append("grant_type","client_credentials"),j.append("client_id",G.clientId),j.append("client_secret",G.clientSecret),M)j.append("scope",M);let J=await fetch(N,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:j.toString()}),W=await J.json();if(!J.ok)throw L.error("Token acquisition error:",W),Error(`Token acquisition failed: ${W.error||J.statusText} - ${W.error_description||""}`.trim());let E=await S.tokenResponse["~standard"].validate(W);if(E.issues)throw L.error("Token response validation failed:",E.issues),Error(`Token response validation failed: ${E.issues.map((_)=>_.message).join("; ")}`);if(G.tokenStore){let _=new Date(Date.now()+(E.value.expires_in??300)*1000),Y={workload_id:G.clientId,access_token:E.value.access_token,token_type:E.value.token_type,scope:E.value.scope,expires_at:_,created_at:new Date,refresh_token:E.value.refresh_token};await G.tokenStore.set(Y)}return E.value})}async function US(M){if(!l(Z)&&!o(Z)){let J=Z;throw Error(`Acquiring tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode. Current config: hasClientId=${!!J.clientId}, hasClientSecret=${!!J.clientSecret}, hasWorkloadId=${!!J.workloadId}, hasPrivateKey=${!!J.privateKey}, hasJwksUri=${!!J.jwksUri}`)}let G=Z;M=M??G.scope;let N=l(Z)?Z.workloadId:Z.clientId;if(G.tokenStore){let J=await G.tokenStore.get(N);if(J){let W=Date.now(),E=J.expires_at.getTime(),_=G.refreshThreshold*1000;if(W+_<E)return J.access_token;if(G.autoRefresh)try{return(l(Z)?await s(M):await i(M)).access_token}catch(Y){if(W<E)return L.warn("Token refresh failed, using cached token:",Y),J.access_token;throw Y}}}return(l(Z)?await s(M):await i(M)).access_token}async function P(M){if(!l(Z)&&!o(Z))throw Error("Refreshing tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode");let G=Z;return M=M??G.scope,l(G)?await s(M):await i(M)}async function u(M){if(!l(Z)&&!o(Z))throw Error("Revoking tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode");let G=Z;try{if(!Z.revocationEndpoint)return;let N=new URLSearchParams;if(N.append("token",M),N.append("token_type_hint","access_token"),l(Z)){let J=Z;N.append("client_id",J.workloadId)}else if(o(Z)){let J=Z;N.append("client_id",J.clientId),N.append("client_secret",J.clientSecret)}let j=await fetch(Z.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:N.toString()});if(!j.ok)L.warn("Token revocation failed:",j.status,j.statusText);else L.info("Token revoked successfully");if(Z.tokenStore){let J;if(l(Z))J=Z.workloadId;else if(o(Z))J=Z.clientId;else return;await Z.tokenStore.delete(J)}}catch(N){L.warn("Error revoking token:",N)}}async function x(){if(!Z?.jwksUri)throw Error("No JWKS URI configured in Workload Config");let M=Z.jwksUri,G=LL.get(M);if(G)return G;return g(async()=>{let N=await fetch(M);if(!N.ok)throw Error("Failed to fetch JWKS");let j=await N.json();return LL.set(M,j),j})}async function v(M){let N=(await x()).keys.find((W)=>W.kid===M);if(!N)throw Error("Public key not found");let j=l(Z)?Z.algorithm:"RS256",J=q(N.alg||j);return crypto.subtle.importKey("jwk",N,J,!1,["verify"])}async function b(M){try{let G=M.split(".");if(G.length!==3)throw Error("Invalid JWT");let N=JSON.parse(O(G[0])),j=JSON.parse(O(G[1])),J=await v(N.kid),W=G[2],_=new TextEncoder().encode(`${G[0]}.${G[1]}`),Y=Uint8Array.from(O(W),(c)=>c.charCodeAt(0)),B=q(N.alg);if(!await crypto.subtle.verify(B,J,Y,_))throw Error("Invalid JWT signature");let w=await S.jwtAssertionClaims["~standard"].validate(j);if(w.issues)throw L.error("JWT claims validation failed:",w.issues),Error(`JWT claims validation failed: ${w.issues.map((c)=>c.message).join("; ")}`);return w.value}catch(G){throw L.error("Error verifying JWT:",G),G}}async function h(M){if(!l(Z)&&!o(Z)&&!vS(Z))throw Error("Validating tokens is only available in JWT Bearer Grant, OAuth2 Client Credentials, or Server-Only mode");try{let G=await b(M),N=Math.floor(Date.now()/1000);if(G.exp&&G.exp<N)return{valid:!1,error:"Token expired"};if(l(Z)){if(Z.audience&&G.aud!==Z.audience)return{valid:!1,error:"Invalid audience"}}else if(o(Z)){if(Z.issuer&&G.iss!==Z.issuer)return{valid:!1,error:"Invalid issuer"};if(Z.audience&&G.aud!==Z.audience)return{valid:!1,error:"Invalid audience"}}else{let j=Z;if(j.issuer&&G.iss!==j.issuer)return{valid:!1,error:"Invalid issuer"}}return{valid:!0,claims:G,expiresAt:G.exp?new Date(G.exp*1000):void 0}}catch(G){return{valid:!1,error:G instanceof Error?G.message:String(G)}}}async function I(M){let G=M.headers.get("Authorization");if(!G||!G.startsWith("Bearer "))return;let N=G.substring(7),j=await h(N);if(!j.valid||!j.claims)return;return{workloadId:j.claims.sub,clientId:typeof j.claims.client_id==="string"?j.claims.client_id:void 0,scope:j.claims.scope,claims:j.claims}}async function m(M){if(!Z)throw Error("Enterprise Standard Workload Manager not initialized");let G=new URL(M.url).pathname,N=(Y)=>{if(!Y)return;try{return new URL(Y).pathname}catch{return Y.startsWith("/")?Y:`/${Y}`}},j=Z._handlerTokenUrl;if(N(j||Z.tokenUrl)===G&&M.method==="GET")try{let B=new URL(M.url).searchParams.get("scope")||void 0,A=await US(B);return new Response(JSON.stringify({access_token:A,token_type:"Bearer"}),{headers:[["Content-Type","application/json"]]})}catch(Y){return L.error("Error in token endpoint:",Y),new Response(JSON.stringify({error:Y instanceof Error?Y.message:"Internal server error"}),{status:500,headers:[["Content-Type","application/json"]]})}if(N(Z.validateUrl)===G&&M.method==="POST"){let Y=M.headers.get("Authorization");if(!Y||!Y.startsWith("Bearer "))return new Response(JSON.stringify({valid:!1,error:"Missing Authorization header"}),{status:401,headers:[["Content-Type","application/json"]]});let B=Y.substring(7),A=await h(B);return new Response(JSON.stringify(A),{status:A.valid?200:401,headers:[["Content-Type","application/json"]]})}if(N(Z.jwksUrl)===G&&M.method==="GET"){let Y=await x();return new Response(JSON.stringify(Y),{headers:[["Content-Type","application/json"]]})}if(N(Z.refreshUrl)===G&&M.method==="POST")try{let Y=await P();return new Response(JSON.stringify(Y),{headers:[["Content-Type","application/json"]]})}catch(Y){return L.error("Error in refresh endpoint:",Y),new Response(JSON.stringify({error:Y instanceof Error?Y.message:"Internal server error"}),{status:500,headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...Z,getToken:US,refreshToken:P,generateJWTAssertion:t,revokeToken:u,validateToken:h,getWorkloadIdentity:I,parseJWT:b,handler:m}}function bS(S){return S=S??"Workload authentication unavailable",new Response(JSON.stringify({error:S}),{status:503,statusText:S,headers:{"Content-Type":"application/json"}})}var jS="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.",mL="EnterpriseStandard or Workload instance is required. Create an ES with enterpriseStandard(source, config) or pass a Workload instance.";async function CL(S,L){r(L,jS);let $=L.workload;if(!$)return;return $.getWorkloadIdentity(S)}async function uL(S,L,$){r(L,jS);let R=L.workload;if(!R)throw bS();return R.getToken($,{client:S})}async function hL(S,L){r(L,mL);let $="validateToken"in L&&typeof L.validateToken==="function"?L:L.workload;if(!$)return{valid:!1,error:"Workload authentication unavailable"};let R=S.headers.get("Authorization");if(!R||!R.startsWith("Bearer "))return{valid:!1,error:"Missing or invalid Authorization header"};let U=R.substring(7);return $.validateToken(U)}async function dL(S,L){r(L,jS);let $=L.workload;if(!$)throw bS();return $.revokeToken(S)}async function cL(S,L){r(L,jS);let $=L.workload;if(!$)throw bS();return $.handler(S)}export*from"@enterprisestandard/core";import{InMemoryTenantStore as FR,parseTenantRequest as qR,sendTenantWebhook as jR,TenantRequestError as TR,tenant as AR}from"@enterprisestandard/core";import{callback as VR,ciam as OR,getCIAMUser as IR,getRequiredSSOorCIAMUser as WR,getSSOorCIAMUser as xR,getSSOorCIAMUser as wR,getSSOUser as yR,iam as kR,initiateLogin as vR,logout as bR,logoutBackChannel as mR,sso as CR,verifyUser as uR}from"@enterprisestandard/core/server";import{setActiveSession as nL}from"@enterprisestandard/core";async function fL(S,L){let $=[];for(let[R,U]of L.entries()){if(!U.sso)continue;try{let D=await U.sso.getUser(S);if(!D)continue;$.push({clientId:R,user:D,valid:!0,expiresAt:D.sso?.expires})}catch{}}return $}async function gL(S,L,$,R={}){let U=$.get(L);if(!U?.sso)return new Response(JSON.stringify({error:"Unknown tenant session"}),{status:404,headers:{"Content-Type":"application/json"}});if(await U.sso.getUser(S)){let z=nL(L,{cookieName:R.activeSessionCookieName,path:R.cookiePath,secure:R.cookieSecure,sameSite:R.cookieSameSite,maxAge:R.cookieMaxAge});return new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json","Set-Cookie":z}})}let X=R.loginUrl??U.sso.loginUrl;if(!X)return new Response(JSON.stringify({error:"Session expired"}),{status:401,headers:{"Content-Type":"application/json"}});let F=new URL(X,S.url);if(!F.searchParams.has("clientId"))F.searchParams.set("clientId",L);return new Response(null,{status:302,headers:{Location:F.toString()}})}async function sL(S,L,$){await S.putSecret(L,$)}function lL(S){let{type:L,...$}=S;return _S({type:"vault",...$})}function a(S){if(!S)return;try{return new URL(S,"http://dummy").pathname}catch{return S.startsWith("/")?S:`/${S}`}}function eL(S,L){if(S?.sso?.redirectUri&&L.sso?.redirectUri){let $=a(S.sso.redirectUri),R=a(L.sso.redirectUri);if($!==R)throw Error(`redirectUri path in framework config must match ConfigSource redirectUri path. ConfigSource path: ${$}, framework path: ${R}`)}}function CS(S){let L={};if(!S)return L;for(let[$,R]of Object.entries(S))if(R.type==="lfv")L[$]=R;return L}function oL(S){return S[VS]}function S$(S,L){let $=CS(S.secrets),R=a(L.deliveryEndpoint),U=a(L.eventsEndpoint),D=a(L.path);for(let X of Object.values($)){if(a(X.deliveryEndpoint)!==R)continue;if(a(X.eventsEndpoint)!==U)continue;let F=X.path?a(X.path):void 0;if(D&&F&&D!==F)continue;return!0}return!1}function L$(S,L){let $=oL(L);if(!$)return S;if(S$(S,$))return S;let R={type:"lfv",path:$.path,lfvServerUrl:$.lfvServerUrl,clientId:$.clientId,signature:$.signature,deliveryTimeout:$.deliveryTimeout,retryInterval:$.retryInterval,warnInterval:$.warnInterval,deliveryEndpoint:$.deliveryEndpoint,eventsEndpoint:$.eventsEndpoint,verifyPublicKey:$.verifyPublicKey},U=S.secrets??{},D="LFV_BOOTSTRAP",X=1;while(D in U)X+=1,D=`LFV_BOOTSTRAP_${X}`;return{...S,secrets:{...U,[D]:R}}}function $$(S,L){let $=CS(S.secrets),R=CS(L.secrets);for(let[U,D]of Object.entries(R)){let X=$[U];if(!X)continue;let F=a(X.deliveryEndpoint),z=a(D.deliveryEndpoint);if(F&&z&&F!==z)throw Error(`LFV deliveryEndpoint path for secrets source "${U}" in framework config must match ConfigSource path. ConfigSource path: ${F}, framework path: ${z}`);let Z=a(X.eventsEndpoint),Q=a(D.eventsEndpoint);if(Z&&Q&&Z!==Q)throw Error(`LFV eventsEndpoint path for secrets source "${U}" in framework config must match ConfigSource path. ConfigSource path: ${Z}, framework path: ${Q}`)}}function RL(S,L){if(L===void 0)return!1;return JSON.stringify(S)===JSON.stringify(L)}function DL(S,L,$,R,U){let D={logger:R,tenantId:S.tenantId,config:S,handler:async()=>new Response("Not Found",{status:404})};return D.workload=RS($.workload,R,S?.workload,L.workload),D.secrets=kS($.secrets,R,S?.secrets,L?.secrets),D.sso=aL($.sso,R,S?.sso,L.sso),D.iam=rL($.iam,R,D.workload,S?.iam,L.iam),D.tenants=pL($.tenant,R,S?.tenant,L.tenant),D.ciam=tL($.ciam,R,S?.ciam,L.ciam,D.workload),D.handler=async(X)=>aS(X,D,U?.routing),D}function R$(S,L,$,R,U,D){eL(L,$),$$(L,$);let X=DL(L,$,R,U,D);S.tenantId=L.tenantId,S.config=L,S.logger=U,S.workload=X.workload,S.secrets=X.secrets,S.sso=X.sso,S.iam=X.iam,S.tenants=X.tenants,S.ciam=X.ciam,S.handler=X.handler}function U$(S,L,$,R){let U=S,D=L;if(R?.beforeChange){let X=R.beforeChange(S,L,$);if(X?.config!==void 0)U=X.config;if(X?.frameworkConfig!==void 0)D=X.frameworkConfig}return{effectiveRemoteConfig:U,effectiveFrameworkConfig:D}}function UL(S){return!!S&&typeof S==="object"&&typeof S.load==="function"}function TS(S){if(!S||typeof S!=="object")return!1;let L=S;return"beforeChange"in L||"afterChange"in L||"routing"in L}async function KR(S,L,$){let R,U,D,X=!1;if(UL(S))R=S,U=TS(L)?void 0:L,D=TS(L)?L:$;else X=!0,R=xS(),U=S,D=TS(L)?L:$;if(UL(S)&&TS(L)&&$)D=$;if(X&&!process.env.ES_CONFIG_TYPE)(U?.logger??mS).warn?.("enterpriseStandard() defaulted to envConfig() with no ES_CONFIG_TYPE set. Falling back to dev config source.");if(X&&!U)U=FS();let F=lS(U,D);U=F.config,D=F.options;let z=L$(U??{},R),Z=z.validators||iL(),Q=z.logger||mS,K,T=z,y=DL({},z,Z,Q,D);function d(H){if(K!==void 0&&RL(H,K))return;let O=K,{effectiveRemoteConfig:q,effectiveFrameworkConfig:V}=U$(H,T,K,D);if(K!==void 0&&RL(q,K)&&V===T)return;let k=V.logger||mS;R$(y,q,V,Z,k,D),K=q,T=V,z=V,Z=V.validators??Z,D?.afterChange?.(y,q,T,O)}if(y.reload=async()=>{let H=await R.load();d(H)},y.reconfigure=async(H)=>{if(H!=null)z={...z,...H},T=z,Z=z.validators??Z;let O=await R.load();d(O)},R.subscribe)R.subscribe((H)=>d(H));return R.load().then((H)=>d(H),(H)=>Q.warn?.("ConfigSource initial load failed",H)),y}export{sL as writeEsaConfigToVault,cL as workloadHandler,RS as workload,uR as verifyUser,NS as vaultConfig,hL as validateWorkloadToken,AR as tenantManagement,gL as switchSession,CR as sso,jR as sendTenantWebhook,kS as secrets,dL as revokeWorkloadToken,qR as parseTenantRequest,lL as openbaoVault,mR as logoutBackChannel,bR as logout,IS as localFileConfig,OS as lfvConfig,vR as initiateLogin,kR as iam,uL as getWorkloadToken,CL as getWorkload,wR as getUser,xR as getSSOorCIAMUser,yR as getSSOUser,WR as getRequiredSSOorCIAMUser,IR as getCIAMUser,MS as gcpConfig,xS as envConfig,KR as enterpriseStandard,FS as dynamicConfig,fL as discoverSessions,PS as devConfig,OR as ciam,VR as callback,GS as azureConfig,ZS as awsConfig,TL as adaptiveFramework,TR as TenantRequestError,$S as InMemoryWorkloadTokenStore,JS as InMemoryUserStore,FR as InMemoryTenantStore,HS as InMemorySessionStore,KS as InMemoryMagicLinkStore,ES as InMemoryGroupStore};
|
|
1
|
+
import{createValidators as aL,defaultLogger as dS,tenant as eL}from"@enterprisestandard/core";import{ciam as oL,iam as S$,sso as L$}from"@enterprisestandard/core/server";function MS(S){throw Error("Not implemented")}function NS(S){throw Error("Not implemented")}function IS(S){return console.warn("ES_CONFIG_TYPE is not set. For LLM documentation, see https://enterprisestandard.com/llms.txt"),console.warn(`If this is a local development environment, visit https://ionite.com/dev?appId=${S.appId??""} to get started, or run: npx @enterprisestandard/cli`),{load:async()=>{return{}},subscribe(L){let $=()=>{};return()=>{}}}}function HS(S){throw Error("Not implemented")}var YS=new Map;function QL(S){if(!S)return"/";return S.startsWith("/")?S:`/${S}`}function zL(S){try{let L=new URL(S),$=L.pathname.replace(/\/+$/g,"");return`${L.origin}${$}`}catch{return S.replace(/\/+$/g,"")}}function nS(S){let L=zL(S.lfvServerUrl),$=QL(S.path);return`${L}|${$}`}function fS(S,L,$){let R=YS.get(S)??new Map;return R.set(L,$),YS.set(S,R),()=>{let U=YS.get(S);if(!U)return;if(U.delete(L),U.size===0)YS.delete(S)}}async function gS(S,L,$){let R=YS.get(S);if(!R)return 0;let U=0;for(let[D,X]of R){if($&&D===$)continue;if(!X.onDelivery)continue;U+=1,await X.onDelivery(L)}return U}async function sS(S,L,$){let R=YS.get(S);if(!R)return 0;let U=0;for(let[D,X]of R){if($&&D===$)continue;if(!X.onEvents)continue;U+=1,await X.onEvents(L)}return U}function lS(S){try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}var ML=1e4,NL=1e4;async function iS(S){await new Promise((L)=>setTimeout(L,S))}function SS(S){return{startedAt:Date.now(),timeout:typeof S?.timeout==="number"&&S.timeout>0?S.timeout:void 0}}function KS(S){if(S.timeout===void 0)return;let L=Date.now()-S.startedAt;return Math.max(0,S.timeout-L)}function XS(S,L,$){return Error(`LFV ${S} timed out after ${$.timeout??0}ms for ${L}`)}async function GS(S,L,$,R,U){let D=KS($);if(D!==void 0){if(D<=0)throw XS(R,U,$);let X=new AbortController,J=setTimeout(()=>X.abort(),D);try{return await fetch(S,{...L,signal:X.signal})}catch(M){if(M instanceof Error&&M.name==="AbortError")throw XS(R,U,$);throw M}finally{clearTimeout(J)}}return await fetch(S,L)}async function pS(S,L,$,R,U,D){let X=0,J=Date.now();for(;;){let M=KS(L);if(M!==void 0&&M<=0)throw XS(R,$,L);try{return await S()}catch(Z){if(X+=1,D>0&&Date.now()-J>=D){let K=Z instanceof Error?Z.message:String(Z);console.warn(`Error connecting to the LFV source. Retries: '${X}' Error: ${K}`),J=Date.now()}let z=M===void 0?U:Math.min(U,M);if(z<=0)throw XS(R,$,L);await iS(z)}}}function HL(S){return typeof S==="object"&&S!==null&&!Array.isArray(S)}function ES(S){let{lfvServerUrl:L,clientId:$,path:R}=S,U=S.signature??"sdk-placeholder-signature",D=typeof S.deliveryTimeout==="number"&&S.deliveryTimeout>0?S.deliveryTimeout:void 0,X=typeof S.retryInterval==="number"&&S.retryInterval>0?S.retryInterval:ML,J=typeof S.warnInterval==="number"&&S.warnInterval>=0?S.warnInterval:NL,M=lS(S.deliveryEndpoint),Z=lS(S.eventsEndpoint),z=nS({lfvServerUrl:L??"",path:R??""}),K=crypto.randomUUID(),P=new Map,y=new Map,n=new Map,E;function w(){let _=P.size>0,Y=n.size>0,F=_||Y;if(F&&!E){E=fS(z,K,{onDelivery:async(A)=>{j(A)},onEvents:async(A)=>{I(A)}});return}if(!F&&E)E(),E=void 0}function q(_){if(!L)throw Error(`LFV source requires "lfvServerUrl" for path ${_}`);if(!$)throw Error(`LFV source requires "clientId" for path ${_}`);return{lfvUrl:L,clientId:$}}async function V(_){return _.text().catch(()=>"")}async function k(_,Y,F,A){let O=q(_),d=F??crypto.randomUUID(),h=A??SS(),f={request_id:d,path:_,action:Y},c=await pS(async()=>{return await GS(`${O.lfvUrl.replace(/\/+$/g,"")}/clients/${O.clientId}/otp`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":d,"X-LFV-Signature":U},body:JSON.stringify(f)},h,"issueOtp",_)},h,_,"issueOtp",X,J);if(c.status!==200){let o=await V(c);throw Error(`LFV OTP request failed (${c.status}) for ${_}: ${o}`)}let _S=await c.json();if(!_S.otp)throw Error(`LFV OTP response missing otp for ${_}`);return _S.otp}async function g(_,Y,F,A,O,d){let h=q(Y),f=O??crypto.randomUUID(),c=d??SS(),_S=await k(Y,F,f,c),o=await pS(async()=>{return await GS(`${h.lfvUrl.replace(/\/+$/g,"")}${_}`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":f,"X-LFV-Signature":U},body:JSON.stringify({request_id:f,otp:_S,path:Y,...A??{}})},c,F,Y)},c,Y,F,X,J);if(o.status!==200&&o.status!==202){let QS=await V(o);throw Error(`LFV ${F} failed (${o.status}) for ${Y}: ${QS}`)}return{requestId:f}}async function t(_,Y,F){let A=y.get(_);if(A)return A;let O=F?.timeout??D,d={startedAt:Date.now(),timeout:typeof O==="number"&&O>0?O:void 0},h,f=new Promise((i)=>{h={resolve:i};let LS=n.get(_)??new Set;LS.add(h),n.set(_,LS),w()}),c=()=>{if(!h)return;let i=n.get(_);if(i?.delete(h),i&&i.size===0)n.delete(_);w()},_S=Y??crypto.randomUUID(),o=0,QS=Date.now();for(;;)try{await g("/secrets/request",_,"read_secret",void 0,_S,d);break}catch(i){let LS=KS(d);if(LS!==void 0&&LS<=0)throw c(),XS("read_secret",_,d);if(o+=1,J>0&&Date.now()-QS>=J){let GL=i instanceof Error?i.message:String(i);console.warn(`LFV read_secret retrying for ${_}. Retries: '${o}' Error: ${GL}`),QS=Date.now()}let zS=LS===void 0?X:Math.min(X,LS);if(zS<=0)throw c(),XS("read_secret",_,d);await iS(zS)}let WS=KS(d);if(WS!==void 0){if(WS<=0)throw c(),Error(`LFV delivery timed out while reading ${_}`);let i;try{return await Promise.race([f,new Promise((LS,zS)=>{i=setTimeout(()=>{c(),zS(Error(`LFV delivery timed out while reading ${_}`))},WS)})])}finally{if(i)clearTimeout(i)}}return await f}function s(_,Y){y.set(_,Y);let F=P.get(_);if(!F)return;for(let A of F)A(Y)}async function p(_,Y){return await t(_,void 0,Y)}async function DS(_,Y,F){if(!HL(Y))throw Error(`putSecret requires an object value for LFV source at path ${_}`);let A=SS(F);if(await x(_,F)){await g("/secrets/update",_,"update_secret",{data:Y},void 0,A);return}await g("/secrets/create",_,"create_secret",{data:Y},void 0,A)}async function T(_,Y){let F=SS(Y);await g("/secrets/delete",_,"delete_secret",void 0,void 0,F)}async function C(_,Y){let F=q(_),A=SS(Y),O=crypto.randomUUID(),d=await k(_,"list_paths",O,A),h=await GS(`${F.lfvUrl.replace(/\/+$/g,"")}/paths/list`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":O,"X-LFV-Signature":U},body:JSON.stringify({request_id:O,otp:d,path:_})},A,"listPaths",_);if(h.status!==200){let c=await V(h);throw Error(`LFV listPaths failed (${h.status}) for ${_}: ${c}`)}let f=await h.json();if(!Array.isArray(f.items))throw Error(`LFV listPaths returned invalid payload for ${_}`);return f.items.filter((c)=>typeof c==="string")}async function x(_,Y){let F=q(_),A=SS(Y),O=crypto.randomUUID(),d=await k(_,"read_metadata",O,A),h=await GS(`${F.lfvUrl.replace(/\/+$/g,"")}/paths/exists`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":O,"X-LFV-Signature":U},body:JSON.stringify({request_id:O,otp:d,path:_})},A,"exists",_);if(h.status!==200){let c=await V(h);throw Error(`LFV exists failed (${h.status}) for ${_}: ${c}`)}let f=await h.json();if(typeof f.exists!=="boolean")throw Error(`LFV exists returned invalid payload for ${_}`);return f.exists}async function v(_,Y,F){let A=SS(F);await g("/secrets/rotate/request",_,"request_rotate",{reason:Y?.reason,severity:Y?.severity,incident_ref:Y?.incidentRef},void 0,A)}async function b(_,Y,F){let A=SS(F);await g("/secrets/revoke/request",_,"request_revoke",{reason:Y?.reason,severity:Y?.severity,incident_ref:Y?.incidentRef},void 0,A)}async function u(_,Y){let F=q(_),A=SS(Y),O=crypto.randomUUID(),d=await k(_,"read_metadata",O,A),h=await GS(`${F.lfvUrl.replace(/\/+$/g,"")}/paths/metadata/read`,{method:"POST",headers:{"Content-Type":"application/json","X-LFV-Request-Id":O,"X-LFV-Signature":U},body:JSON.stringify({request_id:O,otp:d,path:_})},A,"getMetadata",_);if(h.status!==200){let c=await V(h);throw Error(`LFV getMetadata failed (${h.status}) for ${_}: ${c}`)}let f=await h.json();if(!f.metadata||typeof f.metadata!=="object")throw Error(`LFV getMetadata returned invalid payload for ${_}`);return f.metadata}function W(_,Y){let F=P.get(_)??new Set;F.add(Y),P.set(_,F);let A=y.get(_);if(A)Y(A);return w(),()=>{let O=P.get(_);if(!O)return;if(O.delete(Y),O.size===0)P.delete(_);w()}}function m(_){return _.method==="POST"&&new URL(_.url).pathname===M}function Q(_){return _.method==="POST"&&new URL(_.url).pathname===Z}function G(_){let Y=_.data?.metadata?.path;if(typeof Y==="string"&&Y)return Y;if(typeof _.path==="string"&&_.path)return _.path;return}function N(_,Y){let F=n.get(_);if(!F||F.size===0)return!1;n.delete(_),w();for(let A of F)A.resolve(Y);return!0}function j(_){let Y=G(_);if(!Y)return{handled:!1};let F=_.data?.metadata??{},A=typeof F.version==="number"?F.version:0,O={data:_.data?.data??{},metadata:{path:Y,version:A,created:new Date}};return s(Y,O),{handled:N(Y,O)}}async function B(_){let Y=await _.json(),F=j(Y),A=await gS(z,Y,K);if(!F.handled&&A===0)return new Response(JSON.stringify({status:"accepted",note:"unmapped_delivery"}),{status:200,headers:{"Content-Type":"application/json"}});return new Response(JSON.stringify({status:"accepted"}),{status:200,headers:{"Content-Type":"application/json"}})}function I(_){if(!_?.path||typeof _.path!=="string")return;if(_.event==="created"||_.event==="updated"||_.event==="rotated"||_.event==="revoked")t(_.path,_.request_id).catch(()=>{})}async function H(_){let Y=await _.json();if(!Y?.path||typeof Y.path!=="string")return new Response(JSON.stringify({error:"invalid_request",message:"path is required"}),{status:400,headers:{"Content-Type":"application/json"}});return I(Y),await sS(z,Y,K),new Response(JSON.stringify({status:"accepted"}),{status:200,headers:{"Content-Type":"application/json"}})}return{type:S.type,getFullSecret:p,getSecret:async(_,Y)=>{return(await p(_,Y)).data},putSecret:DS,deleteSecret:T,listPaths:C,exists:x,requestRotate:v,requestRevoke:b,getMetadata:u,subscribe:W,isDeliveryRequest:m,isEventsRequest:Q,handleDelivery:B,handleEvents:H}}function $S(S,L,$){if(typeof S!=="string"||S.trim()==="")throw Error(`"${L}" is required when using ${$}`);return S}var wS="__esLfvBootstrap";function xS(S){let L=$S(S.path,"path","lfvConfig"),$=$S(S.deliveryEndpoint,"deliveryEndpoint","lfvConfig"),R=$S(S.eventsEndpoint,"eventsEndpoint","lfvConfig"),U={type:"lfv",path:L,lfvServerUrl:S.lfvServerUrl,clientId:S.clientId,signature:S.signature,deliveryTimeout:S.deliveryTimeout,retryInterval:S.retryInterval,warnInterval:S.warnInterval,deliveryEndpoint:$,eventsEndpoint:R,verifyPublicKey:S.verifyPublicKey},D=S.vault??ES({type:"lfv",path:L,lfvServerUrl:$S(S.lfvServerUrl,"lfvServerUrl","lfvConfig"),clientId:$S(S.clientId,"clientId","lfvConfig"),signature:S.signature,deliveryTimeout:S.deliveryTimeout,retryInterval:S.retryInterval,warnInterval:S.warnInterval,deliveryEndpoint:$,eventsEndpoint:R,verifyPublicKey:S.verifyPublicKey}),X={load:async()=>{try{return(await D.getFullSecret(L)).data}catch(J){throw Error("Error retrieving remote config from LFV",{cause:J})}},subscribe:(J)=>{return D.subscribe(L,(M)=>{J(M.data)})}};return X[wS]=U,X}import{readFile as KL}from"node:fs";import{parseJsonc as EL}from"@enterprisestandard/core";function yS(S){let L=S.path??"es-config.jsonc",$=S.watch===!0;return{load:()=>{return new Promise((U,D)=>{KL(L,"utf-8",(X,J)=>{if(X){D(Error(`Failed to read config file "${L}": ${X.message}`));return}try{U(EL(J))}catch(M){let Z=M instanceof Error?M.message:String(M);D(Error(`Invalid JSON/JSONC in "${L}": ${Z}`))}})})},subscribe(U){throw Error("TODO: subscribe not implemented for local file config source")}}}function ZS(S){let{type:L="vault",url:$,token:R,ttl:U}=S;if(!$)throw Error("OpenBao/Hashicorp compatible vaults require a non-empty url");if(!R)console.log("OpenBao/Hashicorp compatible vaults usually require a token, but one was not provided. Vault requests may fail.");if(U&&U<600000)throw Error("OpenBao/Hashicorp compatible vaults require ttl to be set and greater than 600_000 milliseconds (10 minutes), as not to overload the vault with polling requests");let D={"Content-Type":"application/json"};if(R)D["X-Vault-Token"]=R;function X(E){return typeof E==="object"&&E!==null&&!Array.isArray(E)}async function J(E,w){let q=await fetch(`${$}/${E}`,{headers:{...D}});if(q.status!==200){let k=q.status===401||q.status===403?`Vault returned ${q.status} ${q.statusText} (auth error) from URL: ${$}/${E}`:`Vault returned invalid status, ${q.status}: '${q.statusText}' from URL: ${$}/${E}`;throw Error(k)}try{return(await q.json()).data}catch(V){throw Error("Error retrieving secret",{cause:V})}}async function M(E,w,q){if(!X(w))throw Error(`putSecret requires an object value for vault source at path ${E}`);let V=await fetch(`${$}/${E}`,{method:"POST",headers:D,body:JSON.stringify(w)});if(V.status!==200&&V.status!==201&&V.status!==204){let k=await V.text().catch(()=>"");throw Error(`Vault putSecret failed (${V.status}) for ${$}/${E}: ${k}`)}}async function Z(E,w){let q=await fetch(`${$}/${E}`,{method:"DELETE",headers:D});if(q.status!==200&&q.status!==202&&q.status!==204){let V=await q.text().catch(()=>"");throw Error(`Vault deleteSecret failed (${q.status}) for ${$}/${E}: ${V}`)}}async function z(E,w){let q=`${$}/${E}`,V=async(s)=>{if(s==="LIST")return fetch(q,{method:"LIST",headers:D});let p=q.includes("?")?"&":"?";return fetch(`${q}${p}list=true`,{method:"GET",headers:D})},k=await V("LIST");if(k.status===405||k.status===501)k=await V("GET");if(k.status!==200){let s=await k.text().catch(()=>"");throw Error(`Vault listPaths failed (${k.status}) for ${$}/${E}: ${s}`)}let g=await k.json().catch(()=>null),t;if(g&&typeof g==="object"){let s=g,p=s.data;if(p&&typeof p==="object")t=p.keys;else t=s.keys}if(!Array.isArray(t))throw Error(`Vault listPaths returned an unexpected response for ${$}/${E}`);return t.filter((s)=>typeof s==="string")}async function K(E,w){let q=await fetch(`${$}/${E}`,{headers:D});if(q.status===200)return!0;if(q.status===404)return!1;if(q.status===401||q.status===403)throw Error(`Vault exists failed (${q.status}) for ${$}/${E}: permission denied`);let V=await q.text().catch(()=>"");throw Error(`Vault exists failed (${q.status}) for ${$}/${E}: ${V}`)}async function P(E,w,q){throw Error(`Vault requestRotate is not implemented for source ${L} at path ${E}`)}async function y(E,w,q){throw Error(`Vault requestRevoke is not implemented for source ${L} at path ${E}`)}async function n(E,w){return(await J(E,w)).metadata}return{type:L,getFullSecret:J,getSecret:async(E,w)=>{return(await J(E,w)).data},putSecret:M,deleteSecret:Z,listPaths:z,exists:K,requestRotate:P,requestRevoke:y,getMetadata:n,subscribe:(E,w)=>{if(!U)return console.warn("OpenBao/Hashicorp compatible vaults require ttl to be set if you want to subscribe to changes"),()=>{};let q,V=setInterval(async()=>{try{let k=await J(E);if(q===void 0){q=k.metadata.version;return}if(k.metadata.version!==q)q=k.metadata.version,w(k)}catch(k){console.warn(`Error retrieving remote config from vault. Retrying in ${S.ttl} milliseconds`,k)}},U);return()=>clearInterval(V)}}}function tS(S){if(!S||typeof S!=="object"||Array.isArray(S))return{};let L=S;if(!(("tenantId"in L)||("sso"in L)||("iam"in L)||("workload"in L)||("secrets"in L)||("tenant"in L)||("ciam"in L))&&Object.keys(L).length===1&&"data"in L){let R=L.data;if(R&&typeof R==="object"&&!Array.isArray(R))return R}return L}function BS(S){let L=$S(S.path,"path","vaultConfig"),$=S.vault??ZS({type:"vault",url:S.url,token:S.token,ttl:S.ttl});return{load:async()=>{try{let R=await $.getFullSecret(L);return tS(R.data)}catch(R){if(!S?.retryInterval)throw Error("Error retrieving remote config from vault",{cause:R});else return console.warn(`Error retrieving remote config from vault. Retrying in ${S.ttl} seconds`,R),{}}},subscribe:(R)=>{return $.subscribe(L,(U)=>{R(tS(U.data))})}}}function kS(S){if(!S)return;let L=Number.parseInt(S,10);return Number.isFinite(L)?L:void 0}function vS(S){let L=S?.type??process.env.ES_CONFIG_TYPE;if(!L||L==="dev"){let $=S??{};return IS({appId:$?.appId??process.env.ES_APP_ID,path:process.env.ES_CONFIG_PATH??$?.path,ioniteUrl:process.env.ES_IONITE_URL??$?.ioniteUrl})}else if(L==="lfv"){let $=S??{};return xS({path:process.env.ES_LFV_PATH??$?.path,lfvServerUrl:process.env.ES_LFV_SERVER_URL??$?.lfvServerUrl,clientId:process.env.ES_LFV_CLIENT_ID??$?.clientId,signature:process.env.ES_LFV_SIGNATURE??$?.signature,deliveryEndpoint:process.env.ES_LFV_DELIVERY_ENDPOINT??$?.deliveryEndpoint,verifyPublicKey:process.env.ES_LFV_VERIFY_PUBLIC_KEY??$?.verifyPublicKey,eventsEndpoint:process.env.ES_LFV_EVENTS_ENDPOINT??$?.eventsEndpoint,deliveryTimeout:kS(process.env.ES_LFV_DELIVERY_TIMEOUT)??$?.deliveryTimeout,retryInterval:kS(process.env.ES_LFV_RETRY_INTERVAL)??$?.retryInterval,warnInterval:kS(process.env.ES_LFV_WARN_INTERVAL)??$?.warnInterval})}else if(L==="localFile"){let $=S??{};return yS({path:process.env.ES_FILE_PATH??$?.path,watch:process.env.ES_FILE_WATCH==="true"||$?.watch,ttl:process.env.ES_FILE_TTL?parseInt(process.env.ES_FILE_TTL,10):void 0})}else if(L==="vault"){let $=S??{};return $.vault?BS($):BS({url:process.env.ES_VAULT_URL??$?.url,token:process.env.ES_VAULT_TOKEN??$?.token,path:process.env.ES_VAULT_PATH??$?.path,ttl:process.env.ES_VAULT_TTL?parseInt(process.env.ES_VAULT_TTL,10):void 0})}else if(L==="azure"){let $=S??{};return $.vault?NS($):NS({apiVersion:process.env.ES_AZURE_API_VERSION??$?.apiVersion,scope:process.env.ES_AZURE_SCOPE??$?.scope,secretNamePrefix:process.env.ES_AZURE_SECRET_NAME_PREFIX??$?.secretNamePrefix,authMethod:process.env.ES_AZURE_AUTH_METHOD??$?.authMethod,tenantId:process.env.ES_AZURE_TENANT_ID??$?.tenantId,clientId:process.env.ES_AZURE_CLIENT_ID??$?.clientId,clientSecret:process.env.ES_AZURE_CLIENT_SECRET??$?.clientSecret,federatedTokenFile:process.env.ES_AZURE_FEDERATED_TOKEN_FILE??$?.federatedTokenFile,managedIdentityClientId:process.env.ES_AZURE_MANAGED_IDENTITY_CLIENT_ID??$?.managedIdentityClientId,imdsApiVersion:process.env.ES_AZURE_IMDS_API_VERSION??$?.imdsApiVersion,vaultUrl:process.env.ES_AZURE_VAULT_URL??$?.vaultUrl,vaultName:process.env.ES_AZURE_VAULT_NAME??$?.vaultName,ttl:process.env.ES_AZURE_TTL?parseInt(process.env.ES_AZURE_TTL,10):void 0})}else if(L==="aws"){let $=S??{};return $.vault?MS($):MS({webhookUrl:process.env.ES_AWS_WEBHOOK_URL??$?.webhookUrl,ttl:process.env.ES_AWS_TTL?parseInt(process.env.ES_AWS_TTL,10):void 0})}else if(L==="gcp"){let $=S??{};return $.vault?HS($):HS({ttl:process.env.ES_GCP_TTL?parseInt(process.env.ES_GCP_TTL,10):void 0})}throw Error(`ES_CONFIG_TYPE="${L}" is not a valid ConfigSourceType when using envConfig().`)}import{defaultLogger as jL}from"@enterprisestandard/core";import{list as BL}from"@enterprisestandard/core";class JS{groups=new Map;externalIdIndex=new Map;displayNameIndex=new Map;async get(S){return this.groups.get(S)??null}async getByExternalId(S){let L=this.externalIdIndex.get(S);if(!L)return null;return this.groups.get(L)??null}async getByDisplayName(S){let L=this.displayNameIndex.get(S.toLowerCase());if(!L)return null;return this.groups.get(L)??null}async list(S){let L=Array.from(this.groups.values()),$=Math.max(0,S?.start??0),R=S?.limit;if(S?.sort?.length)L=[...L].sort((J,M)=>{for(let{field:Z,direction:z}of S.sort){let K=J[Z],P=M[Z],y=JL(K,P);if(y!==0)return z==="desc"?-y:y}return 0});let U=L.length,D=R!=null?$+R:void 0,X=L.slice($,D);return BL(U,X,$,R)}async upsert(S){let L=this.groups.get(S.id);if(L){if(L.externalId&&L.externalId!==S.externalId)this.externalIdIndex.delete(L.externalId);if(L.displayName.toLowerCase()!==S.displayName.toLowerCase())this.displayNameIndex.delete(L.displayName.toLowerCase())}if(this.groups.set(S.id,S),S.externalId)this.externalIdIndex.set(S.externalId,S.id);this.displayNameIndex.set(S.displayName.toLowerCase(),S.id)}async delete(S){let L=this.groups.get(S);if(L){if(L.externalId)this.externalIdIndex.delete(L.externalId);this.displayNameIndex.delete(L.displayName.toLowerCase())}this.groups.delete(S)}async addMember(S,L){let $=this.groups.get(S);if(!$)throw Error(`Group ${S} not found`);let R=$.members??[];if(!R.some((U)=>U.value===L.value))R.push(L),$.members=R,$.updatedAt=new Date}async removeMember(S,L){let $=this.groups.get(S);if(!$)throw Error(`Group ${S} not found`);if($.members)$.members=$.members.filter((R)=>R.value!==L),$.updatedAt=new Date}}function JL(S,L){let $=S===void 0||S===null,R=L===void 0||L===null;if($&&R)return 0;if($)return 1;if(R)return-1;if(S instanceof Date&&L instanceof Date)return S.getTime()-L.getTime();let U=String(S),D=String(L);return U.localeCompare(D)}class FS{magicLinks=new Map;async create(S,L,$){if(this.magicLinks.has(S))throw Error(`Magic link with token ${S} already exists`);let R={token:S,user:L,createdAt:new Date,expiresAt:$};this.magicLinks.set(S,R)}async get(S){let L=this.magicLinks.get(S);if(!L)return null;if(Date.now()>L.expiresAt.getTime())return this.magicLinks.delete(S),null;return L}async delete(S){this.magicLinks.delete(S)}}class qS{sessions=new Map;async create(S){if(this.sessions.has(S.sid))throw Error(`Session with sid ${S.sid} already exists`);this.sessions.set(S.sid,S)}async get(S){return this.sessions.get(S)??null}async update(S,L){let $=this.sessions.get(S);if(!$)throw Error(`Session with sid ${S} not found`);let R={...$,...L};this.sessions.set(S,R)}async delete(S){this.sessions.delete(S)}}import{list as FL}from"@enterprisestandard/core";class jS{users=new Map;emailIndex=new Map;userNameIndex=new Map;async get(S){return this.users.get(S)??null}async getByEmail(S){let L=this.emailIndex.get(S.toLowerCase());if(!L)return null;return this.users.get(L)??null}async getByUserName(S){let L=this.userNameIndex.get(S.toLowerCase());if(!L)return null;return this.users.get(L)??null}async upsert(S){let L=this.users.get(S.id);if(L){if(L.email&&L.email.toLowerCase()!==S.email?.toLowerCase())this.emailIndex.delete(L.email.toLowerCase());if(L.userName&&L.userName.toLowerCase()!==S.userName?.toLowerCase())this.userNameIndex.delete(L.userName.toLowerCase())}if(this.users.set(S.id,S),S.email)this.emailIndex.set(S.email.toLowerCase(),S.id);if(S.userName)this.userNameIndex.set(S.userName.toLowerCase(),S.id)}async delete(S){let L=this.users.get(S);if(L){if(L.email)this.emailIndex.delete(L.email.toLowerCase());if(L.userName)this.userNameIndex.delete(L.userName.toLowerCase())}this.users.delete(S)}async list(S){let L=Array.from(this.users.values()),$=Math.max(0,S?.start??0),R=S?.limit;if(S?.sort?.length)L=[...L].sort((J,M)=>{for(let{field:Z,direction:z}of S.sort){let K=J[Z],P=M[Z],y=qL(K,P);if(y!==0)return z==="desc"?-y:y}return 0});let U=L.length,D=R!=null?$+R:void 0,X=L.slice($,D);return FL(U,X,$,R)}}function qL(S,L){let $=S===void 0||S===null,R=L===void 0||L===null;if($&&R)return 0;if($)return 1;if(R)return-1;if(S instanceof Date&&L instanceof Date)return S.getTime()-L.getTime();return String(S).localeCompare(String(L))}class RS{tokens=new Map;async set(S){this.tokens.set(S.workload_id,S)}async get(S){let L=this.tokens.get(S);if(!L)return null;if(Date.now()>L.expires_at.getTime())return this.tokens.delete(S),null;return L}async delete(S){this.tokens.delete(S)}async isValid(S){return await this.get(S)!==null}async cleanup(){let S=Date.now();for(let[L,$]of this.tokens.entries())if(S>$.expires_at.getTime())this.tokens.delete(L)}}var bS="__esDynamicConfig";function PS(S){if(!S)return;try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}function PL(S){let L=S.workload;if(!L||typeof L!=="object")return;if(typeof L.tokenUrl==="string")return PS(L.tokenUrl);let $=L.incoming;if($&&typeof $.tokenUrl==="string")return PS($.tokenUrl);let R=L.default;if(R&&typeof R.tokenUrl==="string")return PS(R.tokenUrl);return}function TL(S,L,$){let R={...L},U=$.basePath,D=$.stores;if($.validators&&!R.validators)R.validators=$.validators;if($.logger&&!R.logger)R.logger=$.logger;if(S.sso&&!R.sso)R.sso={redirectUri:PS(S.sso.redirectUri)??`${U}/auth/callback`,loginUrl:`${U}/auth/login`,userUrl:`${U}/auth/user`,logoutUrl:`${U}/auth/logout`,logoutBackChannelUrl:`${U}/auth/logout/backchannel`,sessionStore:D.sessionStore,userStore:D.userStore,enableJitUserProvisioning:!0};if(S.iam&&!R.iam)R.iam={usersUrl:`${U}/iam/Users`,groupsUrl:`${U}/iam/Groups`,userStore:D.userStore,groupStore:D.groupStore};if(S.workload&&!R.workload)R.workload={tokenUrl:PL(S)??`${U}/workload/token`,validateUrl:`${U}/workload/validate`,jwksUrl:`${U}/workload/jwks`,refreshUrl:`${U}/workload/refresh`,tokenStore:D.workloadTokenStore};if(S.ciam&&!R.ciam)R.ciam={magicLinkUrl:`${U}/magic-link`,magicLinkLoginUrl:`${U}/magic-link/login`,logoutUrl:`${U}/auth/logout`,logoutBackChannelUrl:`${U}/auth/logout/backchannel`,landingUrl:"/",sessionStore:D.sessionStore,userStore:D.userStore,magicLinkStore:D.magicLinkStore,enableJitUserProvisioning:!0};if(S.tenant&&!R.tenant)R.tenant={};return R}function AL(S,L){return($,R,U)=>{let D=TL($,R,L),X=S?.($,D,U);return{config:X?.config??$,frameworkConfig:X?.frameworkConfig??D}}}function VL(S={}){return{validators:S.validators,logger:S.logger,stores:{sessionStore:S.stores?.sessionStore??new qS,userStore:S.stores?.userStore??new jS,groupStore:S.stores?.groupStore??new JS,magicLinkStore:S.stores?.magicLinkStore??new FS,workloadTokenStore:S.stores?.workloadTokenStore??new RS},basePath:S.basePath??"/api/es"}}function TS(S={}){let L=VL(S);return{validators:L.validators,logger:L.logger,[bS]:L}}function OL(S={}){return TS(S)}function rS(S,L){let $=S??{},R=$[bS];if(!R)return{config:S??{},options:L};let U={...$};delete U[bS];let D={...L??{},beforeChange:AL(L?.beforeChange,R)};return(U.logger??jL).info?.("Dynamic framework configuration enabled",{basePath:R.basePath,adaptiveStores:!0}),{config:U,options:D}}import{logout as aS,logoutBackChannel as eS}from"@enterprisestandard/core/server";function oS(S){if(!S)return;try{return new URL(S).pathname}catch{return S.startsWith("/")?S:`/${S}`}}function SL(S){return S==="/"?S:S.replace(/\/+$/,"")}function WL(S){let L=SL(S);return{matchesPath:(U)=>{if(!U)return!1;let D=oS(U);if(!D)return!1;return SL(D)===L},startsWithPath:(U)=>{if(!U)return!1;let D=oS(U);if(!D)return!1;return S===D||S.startsWith(`${D}/`)}}}function IL(S,L){let $=new URL(S.url).pathname,{matchesPath:R,startsWithPath:U}=WL($);if(L.sso){let D=L.sso;if(R(L.sso.userUrl))return{module:"sso",kind:"sso.user",handler:async(X)=>{let J=await D.handler(X);if(J.status===401&&L.ciam){let M=await L.ciam.getUser(X);if(M)return new Response(JSON.stringify(M),{headers:{"Content-Type":"application/json"}})}return J}};if(R(L.sso.logoutUrl))return{module:"sso",kind:"sso.logout",handler:async(X)=>aS(X,L)};if(R(L.sso.logoutBackChannelUrl))return{module:"sso",kind:"sso.logout_backchannel",handler:async(X)=>eS(X,L)};if(R(L.sso.loginUrl)||R(L.sso.tokenUrl)||R(L.sso.refreshUrl)||R(L.sso.jwksUrl)||R(L.sso.redirectUri))return{module:"sso",kind:"sso.handler",handler:async(X)=>D.handler(X)}}if(L.ciam){if(R(L.ciam.logoutUrl))return{module:"ciam",kind:"ciam.logout",handler:async(D)=>aS(D,L)};if(R(L.ciam.logoutBackChannelUrl))return{module:"ciam",kind:"ciam.logout_backchannel",handler:async(D)=>eS(D,L)}}if(L.iam){let D=L.iam;if(U(L.iam.usersUrl)||U(L.iam.groupsUrl))return{module:"iam",kind:"iam.handler",handler:async(X)=>D.handler(X)}}if(L.workload){let D=L.workload,M=D._handlerTokenUrl??(D.tokenUrl?.startsWith("/")?D.tokenUrl:void 0)??(D.tokenUrl&&!D.tokenUrl.startsWith("http")?D.tokenUrl:void 0),Z="validateUrl"in D?D.validateUrl:void 0,z="jwksUrl"in D?D.jwksUrl:void 0,K="refreshUrl"in D?D.refreshUrl:void 0;if(R(M)||R(Z)||R(z)||R(K))return{module:"workload",kind:"workload.handler",handler:async(P)=>D.handler(P)}}if(L.secrets){let D=L.secrets;if(D.isLfvDeliveryRequest?.(S)&&D.handleLfvDelivery){let X=D.handleLfvDelivery;return{module:"secrets",kind:"secrets.lfv_delivery",handler:async(J)=>X(J)}}if(D.isLfvEventsRequest?.(S)&&D.handleLfvEvents){let X=D.handleLfvEvents;return{module:"secrets",kind:"secrets.lfv_events",handler:async(J)=>X(J)}}}if(L.ciam){let D=L.ciam,X=L.ciam.magicLinkUrl||"/magic-link",J=L.ciam.magicLinkLoginUrl||"/magic-link/login";if(R(X)&&S.method==="POST"||R(J)&&S.method==="GET")return{module:"ciam",kind:"ciam.handler",handler:async(M)=>D.handler(M)}}return}async function LL(S,L,$){if($?.filter){let X=await $.filter(S,L);if(X instanceof Response)return X;if(X==="not_handled")return new Response("Not Found",{status:404})}let R=()=>IL(S,L),U=await $?.resolve?.(S,L,R)??R();if(!U)return new Response("Not Found",{status:404});let D=async()=>U.handler(S);if($?.wrap)return await $.wrap(S,U,D,L);return await D()}import{readFile as wL,stat as xL}from"node:fs/promises";function AS(S,L){if(!S||S.trim().length===0)throw Error(`Missing required Azure config: ${L}`);return S}function yL(S){return S.replace(/^\/+|\/+$/g,"").replaceAll("/","--")}function mS(S,L){return`${S.replace(/\/+$/g,"")}/${L.replace(/^\/+/g,"")}`}function kL(S){try{let $=new URL(S).pathname.split("/").filter(Boolean),R=$.indexOf("secrets");if(R===-1)return;return $[R+2]||void 0}catch{return}}function vL(S){return typeof S==="object"&&S!==null&&!Array.isArray(S)}function $L(S){let L=S.apiVersion??"7.4",$=S.scope??"https://vault.azure.net/.default",R=S.secretNameTransform??yL,U=S.authMethod,D="/var/run/secrets/azure/tokens/azure-identity-token",X=S.federatedTokenFile??"/var/run/secrets/azure/tokens/azure-identity-token",J=S.vaultUrl??(S.vaultName?`https://${S.vaultName}.vault.azure.net`:void 0)??void 0,M=AS(J,"vaultUrl or vaultName (ES_AZURE_KEY_VAULT_URL / ES_AZURE_KEY_VAULT_NAME)");async function Z(T){try{return await xL(T),!0}catch{return!1}}let z,K;async function P(T){let{tenantId:C,clientId:x}=S;if(!C)throw Error("Workload identity requires tenantId");if(!x)throw Error("Workload identity requires clientId");if(!await Z(X))throw Error(`Federated token file not found at ${X}`);let v=(await wL(X,"utf8")).trim();if(!v)throw Error("Federated token file was empty");let b=`https://login.microsoftonline.com/${encodeURIComponent(C)}/oauth2/v2.0/token`,u=new URLSearchParams({client_id:x,grant_type:"client_credentials",scope:$,client_assertion_type:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",client_assertion:v}),W=await fetch(b,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:u});if(W.status!==200){let Q=await W.text().catch(()=>"");throw Error(`Azure workload identity token exchange returned ${W.status} ${W.statusText}. tenantId=${C}. Response: ${Q}`)}let m=await W.json();if(!m?.access_token)throw Error("Azure token response missing access_token");return z={accessToken:m.access_token,expiresAtMs:T+(m.expires_in??0)*1000},m.access_token}async function y(T){let C=S.imdsApiVersion??"2018-02-01",x="https://vault.azure.net",v=new URL("http://169.254.169.254/metadata/identity/oauth2/token");if(v.searchParams.set("api-version",C),v.searchParams.set("resource","https://vault.azure.net"),S.managedIdentityClientId)v.searchParams.set("client_id",S.managedIdentityClientId);let b=await fetch(v.toString(),{headers:{Metadata:"true",Accept:"application/json"}});if(b.status!==200){let m=await b.text().catch(()=>"");throw Error(`Azure IMDS token endpoint returned ${b.status} ${b.statusText}. Response: ${m}`)}let u=await b.json();if(!u?.access_token)throw Error("IMDS token response missing access_token");let W=T+60000;if(u.expires_on){let m=Number.parseInt(u.expires_on,10);if(Number.isFinite(m)&&m>0)W=m*1000;else{let Q=Date.parse(u.expires_on);if(Number.isFinite(Q))W=Q}}else if(u.expires_in){let m=Number.parseInt(u.expires_in,10);if(Number.isFinite(m)&&m>0)W=T+m*1000}return z={accessToken:u.access_token,expiresAtMs:W},u.access_token}async function n(T){let C=AS(S.tenantId,"tenantId (or ES_AZURE_TENANT_ID/AZURE_TENANT_ID)"),x=AS(S.clientId,"clientId (or ES_AZURE_CLIENT_ID/AZURE_CLIENT_ID)"),v=AS(S.clientSecret,"clientSecret (or ES_AZURE_CLIENT_SECRET)"),b=`https://login.microsoftonline.com/${encodeURIComponent(C)}/oauth2/v2.0/token`,u=new URLSearchParams({client_id:x,client_secret:v,grant_type:"client_credentials",scope:$}),W=await fetch(b,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:u});if(W.status!==200){let Q=await W.text().catch(()=>"");throw Error(`Azure token endpoint returned ${W.status} ${W.statusText}. tenantId=${C}. Response: ${Q}`)}let m=await W.json();if(!m?.access_token)throw Error("Azure token response missing access_token");return z={accessToken:m.access_token,expiresAtMs:T+(m.expires_in??0)*1000},m.access_token}async function E(){let T=Date.now();if(z&&z.expiresAtMs-60000>T)return z.accessToken;if(K)return K;K=(async()=>{if(U==="workload_identity")return await P(T);if(U==="managed_identity")return await y(T);if(U==="client_secret")return await n(T);if(await Z(X))try{return await P(T)}catch{}try{return await y(T)}catch{}return await n(T)})();try{return await K}finally{K=void 0}}async function w(T){let C=await E(),x=mS(M,`/secrets/${encodeURIComponent(T)}?api-version=${encodeURIComponent(L)}`),v=await fetch(x,{headers:{Authorization:`Bearer ${C}`,Accept:"application/json"}});if(v.status!==200){let b=await v.text().catch(()=>"");throw Error(`Key Vault returned ${v.status} ${v.statusText} for ${x}. Response: ${b}`)}return await v.json()}async function q(T,C){let x=R(T),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await w(v),u=b.value;try{u=JSON.parse(b.value)}catch{}let W=b.attributes?.created?b.attributes.created*1000:void 0,m=kL(b.id);return{data:u,metadata:{path:T,version:Number.parseInt(m??"",10)||0,created:W?new Date(W):new Date}}}async function V(T,C,x){if(!vL(C))throw Error(`putSecret requires an object value for azure source at path ${T}`);let v=R(T),b=S.secretNamePrefix?`${S.secretNamePrefix}${v}`:v,u=await E(),W=mS(M,`/secrets/${encodeURIComponent(b)}?api-version=${encodeURIComponent(L)}`),m=JSON.stringify({value:JSON.stringify(C)}),Q=await fetch(W,{method:"PUT",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json",Accept:"application/json"},body:m});if(Q.status!==200&&Q.status!==201){let G=await Q.text().catch(()=>"");throw Error(`Key Vault putSecret returned ${Q.status} for ${W}: ${G}`)}}async function k(T,C){let x=R(T),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await E(),u=mS(M,`/secrets/${encodeURIComponent(v)}?api-version=${encodeURIComponent(L)}`),W=await fetch(u,{method:"DELETE",headers:{Authorization:`Bearer ${b}`,Accept:"application/json"}});if(W.status!==200&&W.status!==202&&W.status!==204){let m=await W.text().catch(()=>"");throw Error(`Key Vault deleteSecret returned ${W.status} for ${u}: ${m}`)}}async function g(T,C){throw Error(`listPaths is not implemented for Azure Key Vault source at path ${T}`)}async function t(T,C){try{return await q(T),!0}catch(x){if((x instanceof Error?x.message:String(x)).includes(" 404 "))return!1;throw x}}async function s(T,C,x){throw Error(`requestRotate is not implemented for Azure Key Vault source at path ${T}`)}async function p(T,C,x){throw Error(`requestRevoke is not implemented for Azure Key Vault source at path ${T}`)}async function DS(T,C){let x=R(T),v=S.secretNamePrefix?`${S.secretNamePrefix}${x}`:x,b=await w(v);return{id:b.id,...b.attributes??{}}}return{type:S.type,getFullSecret:q,getSecret:async(T,C)=>{return(await q(T,C)).data},putSecret:V,deleteSecret:k,listPaths:g,exists:t,requestRotate:s,requestRevoke:p,getMetadata:DS,subscribe:(T,C)=>{throw Error("TODO: subscribe not implemented for azure vault")}}}function RL(S){async function L(Z,z){throw Error("Error retrieving secret",{cause:Error("Not implemented")})}async function $(Z,z,K){throw Error("putSecret not implemented for dev vault")}async function R(Z,z){throw Error(`deleteSecret not implemented for dev vault at path ${Z}`)}async function U(Z,z){throw Error(`listPaths not implemented for dev vault at path ${Z}`)}async function D(Z,z){throw Error(`exists not implemented for dev vault at path ${Z}`)}async function X(Z,z,K){throw Error(`requestRotate not implemented for dev vault at path ${Z}`)}async function J(Z,z,K){throw Error(`requestRevoke not implemented for dev vault at path ${Z}`)}async function M(Z,z){throw Error(`getMetadata not implemented for dev vault at path ${Z}`)}return{type:S.type,getFullSecret:L,getSecret:async(Z,z)=>{return(await L(Z,z)).data},putSecret:$,deleteSecret:R,listPaths:U,exists:D,requestRotate:X,requestRevoke:J,getMetadata:M,subscribe:(Z,z)=>{throw Error("TODO: subscribe not implemented for dev vault")}}}function UL(S,L){let $=(R,U)=>{throw Error(`${R} is not implemented for source "${L}" (type: ${S}) at path ${U}`)};return{type:S,getFullSecret:(R,U)=>Promise.reject($("getFullSecret",R)),getSecret:(R,U)=>Promise.reject($("getSecret",R)),putSecret:(R,U,D)=>Promise.reject($("putSecret",R)),subscribe:(R,U)=>{return $("subscribe",R),()=>{}},deleteSecret:(R,U)=>Promise.reject($("deleteSecret",R)),listPaths:(R,U)=>Promise.reject($("listPaths",R)),exists:(R,U)=>Promise.reject($("exists",R)),requestRotate:(R,U,D)=>Promise.reject($("requestRotate",R)),requestRevoke:(R,U,D)=>Promise.reject($("requestRevoke",R)),getMetadata:(R,U)=>Promise.reject($("getMetadata",R))}}function bL(S,L){if(L.type==="vault")return ZS(L);if(L.type==="lfv")return ES(L);if(L.type==="azure")return $L(L);if(L.type==="dev")return RL(L);if(L.type==="aws")return UL(L.type,S);if(L.type==="gcp")return UL(L.type,S);throw Error(`Unsupported secrets source type for "${S}"`)}function mL(S){return S.type==="lfv"&&typeof S.isDeliveryRequest==="function"&&typeof S.isEventsRequest==="function"&&typeof S.handleDelivery==="function"&&typeof S.handleEvents==="function"}function CL(S,L){let $={},R=new Set([...Object.keys(S??{}),...Object.keys(L??{})]);for(let U of R){let D=S?.[U],X=L?.[U];$[U]={...D??{},...X??{}}}return $}function CS(S,L,$,R){if(!$&&!R)return;let U=CL($,R),D={};for(let[z,K]of Object.entries(U))S?.validateSourceConfig?.(z,K),D[z]=bL(z,K);let X=(z)=>{let K=D[z];if(!K)throw L.warn?.(`Secrets source "${z}" is not configured`),Error(`Secrets source "${z}" is not configured`);return K},J=()=>{return Object.values(D).filter(mL)},M=(z)=>{return J().find((K)=>K.isDeliveryRequest(z))},Z=(z)=>{return J().find((K)=>K.isEventsRequest(z))};return{config:D,listSecretsSources:()=>Object.keys(D),getSecretsSource:X,getSecret:(z,K,P)=>X(z).getSecret(K,P),getFullSecret:(z,K,P)=>X(z).getFullSecret(K,P),putSecret:(z,K,P,y)=>X(z).putSecret(K,P,y),deleteSecret:(z,K,P)=>X(z).deleteSecret(K,P),listPaths:(z,K,P)=>X(z).listPaths(K,P),exists:(z,K,P)=>X(z).exists(K,P),requestRotate:(z,K,P,y)=>X(z).requestRotate(K,P,y),requestRevoke:(z,K,P,y)=>X(z).requestRevoke(K,P,y),getMetadata:(z,K,P)=>X(z).getMetadata(K,P),subscribe:(z,K,P)=>X(z).subscribe(K,P),isLfvDeliveryRequest:(z)=>M(z)!==void 0,isLfvEventsRequest:(z)=>Z(z)!==void 0,handleLfvDelivery:async(z)=>{let K=M(z);if(!K)return new Response("Not Found",{status:404});return K.handleDelivery(z)},handleLfvEvents:async(z)=>{let K=Z(z);if(!K)return new Response("Not Found",{status:404});return K.handleEvents(z)}}}import{must as r}from"@enterprisestandard/core";var DL=new Map;function l(S){if(S===void 0||S===null)return!1;let L=S;return L.workloadId!==void 0&&L.workloadId!==null||L.privateKey!==void 0&&L.privateKey!==null}function e(S){if(S===void 0||S===null)return!1;let L=S,$=L.clientId!==void 0&&L.clientId!==null,R=L.clientSecret!==void 0&&L.clientSecret!==null,U=L.workloadId!==void 0&&L.workloadId!==null,D=L.privateKey!==void 0&&L.privateKey!==null;return($||R)&&!U&&!D}function uS(S){if(S===void 0||S===null)return!1;let L=S,$=L.jwksUri!==void 0&&L.jwksUri!==null,R=L.workloadId!==void 0&&L.workloadId!==null,U=L.clientId!==void 0&&L.clientId!==null,D=L.clientSecret!==void 0&&L.clientSecret!==null,X=L.privateKey!==void 0&&L.privateKey!==null;return $&&!R&&!X&&!U&&!D}function _L(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;return"clientId"in L||"jwksUri"in L||"workloadId"in L}function uL(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;if(_L(L))return!1;let $=Object.entries(L);if($.length===0)return!1;return $.every(([,R])=>_L(R))}function hL(S){if(S===null||typeof S!=="object"||Array.isArray(S))return!1;let L=S;if("incoming"in L||"outgoing"in L){if(L.incoming!==void 0&&(typeof L.incoming!=="object"||L.incoming===null))return!1;if(L.outgoing!==void 0&&(typeof L.outgoing!=="object"||L.outgoing===null||Array.isArray(L.outgoing)))return!1;return!0}return!1}function US(S,L,$,R){if(!$&&!R)return;if($&&hL($)){let Q=$.incoming,G=Q?{...Q,...R,jwksUri:Q.jwksUri,issuer:Q.issuer}:R;if(!G||!G.tokenUrl&&!G.jwksUri)L.warn("Workload vault config has incoming/outgoing but no server config (incoming or framework) with tokenUrl/jwksUri; workload module handler will be unavailable.");let N=G&&(G.tokenUrl||G.jwksUri)?US(S,L,Q??void 0,R):void 0,j=Object.entries($.outgoing??{}),B={};for(let[H,_]of j){let Y=US(S,L,_,void 0);if(Y)B[H]=Y}if(!N&&Object.keys(B).length===0)return;return{...N?.config??{},getToken:async(H,_)=>{if(_?.client){let F=B[_.client];if(!F)throw Error(`Unknown workload client: ${_.client}`);return F.getToken(H)}if(N)return N.getToken(H);let Y=Object.keys(B);if(Y.length>1)throw Error(`Multiple named clients are configured, but no client was specified. Available clients: ${Y.join(", ")}`);if(Y.length===1)return B[Y[0]].getToken(H);throw Error("No workload config available; specify options.client")},refreshToken:async(H)=>{if(!N)throw Error("No default workload config");return N.refreshToken(H)},generateJWTAssertion:async(H)=>{if(!N)throw Error("No default workload config");return N.generateJWTAssertion(H)},revokeToken:async(H)=>{if(!N)throw Error("No default workload config");return N.revokeToken(H)},validateToken:async(H)=>{if(!N)throw Error("No default workload config");return N.validateToken(H)},getWorkloadIdentity:async(H)=>{if(!N)return;return N.getWorkloadIdentity(H)},parseJWT:async(H)=>{if(!N)throw Error("No default workload config");return N.parseJWT(H)},handler:async(H)=>{if(!N)return new Response("Not Found",{status:404});return N.handler(H)}}}if($&&uL($)){let Q=$.default,G=Q?{...Q,...R,jwksUri:Q.jwksUri,issuer:Q.issuer}:R;if(!G||!G.tokenUrl&&!G.jwksUri)L.warn('Workload vault config is a clients map but no server config (workload["default"] or framework workload) with tokenUrl/jwksUri; workload module handler will be unavailable.');let N=G&&(G.tokenUrl||G.jwksUri)?US(S,L,Q??void 0,R):void 0,j=Object.entries($).filter(([H])=>H!=="default"),B={};for(let[H,_]of j){let Y=US(S,L,_,void 0);if(Y)B[H]=Y}if(!N&&Object.keys(B).length===0)return;return{...N?.config??{},getToken:async(H,_)=>{if(_?.client){let F=B[_.client];if(!F)throw Error(`Unknown workload client: ${_.client}`);return F.getToken(H)}if(N)return N.getToken(H);let Y=Object.keys(B);if(Y.length>1)throw Error(`Multiple named clients are configured, but no client was specified. Available clients: ${Y.join(", ")}`);if(Y.length===1)return B[Y[0]].getToken(H);throw Error("No workload config available; specify options.client")},refreshToken:async(H)=>{if(!N)throw Error("No default workload config");return N.refreshToken(H)},generateJWTAssertion:async(H)=>{if(!N)throw Error("No default workload config");return N.generateJWTAssertion(H)},revokeToken:async(H)=>{if(!N)throw Error("No default workload config");return N.revokeToken(H)},validateToken:async(H)=>{if(!N)throw Error("No default workload config");return N.validateToken(H)},getWorkloadIdentity:async(H)=>{if(!N)return;return N.getWorkloadIdentity(H)},parseJWT:async(H)=>{if(!N)throw Error("No default workload config");return N.parseJWT(H)},handler:async(H)=>{if(!N)return new Response("Not Found",{status:404});return N.handler(H)}}}let U=$,D=R?.tokenUrl,X=D?.startsWith("/")?D:void 0,J=U?.idpTokenUrl??R?.idpTokenUrl??(U?.tokenUrl&&(U.tokenUrl.startsWith("http://")||U.tokenUrl.startsWith("https://"))?U.tokenUrl:void 0),M={...U,...R,tokenUrl:X??R?.tokenUrl??U?.tokenUrl,idpTokenUrl:J,jwksUri:U?.jwksUri,issuer:U?.issuer};M._handlerTokenUrl=X;let Z,z=M,K=l(M),P=e(M),y=uS(M);if(!K&&!P&&!y){if(!U||Object.keys(U).length===0)return;throw L.error("WorkloadConfig validation failed. Config:",{keys:Object.keys(M),clientId:z.clientId,clientSecret:z.clientSecret?"[REDACTED]":void 0,workloadId:z.workloadId,privateKey:z.privateKey?"[REDACTED]":void 0,jwksUri:z.jwksUri,tokenUrl:z.tokenUrl,idpTokenUrl:z.idpTokenUrl,fromVaultKeys:U?Object.keys(U):[],fromCodeKeys:R?Object.keys(R):[]}),Error("Invalid WorkloadConfig: must provide the correct config for one of the following modes: JWT Bearer Grant, OAuth2 Client Credentials, or Server-Only")}if(K)Z={...M,tokenUrl:M.tokenUrl,idpTokenUrl:r(M.idpTokenUrl,"Missing 'idpTokenUrl' from Workload Config"),workloadId:r(M.workloadId,"Missing 'workloadId' from Workload Config"),privateKey:r(M.privateKey,"Missing 'privateKey' from Workload Config"),audience:r(M.audience,"Missing 'audience' from Workload Config"),scope:M.scope??"",algorithm:M.algorithm??"RS256",tokenLifetime:M.tokenLifetime??300,refreshThreshold:M.refreshThreshold??60,autoRefresh:M.autoRefresh!==void 0?M.autoRefresh:!0,tokenStore:M.tokenStore??new RS};else if(e(M))Z={...M,tokenUrl:M.tokenUrl,idpTokenUrl:r(M.idpTokenUrl,"Missing 'idpTokenUrl' from Workload Config"),clientId:r(M.clientId,"Missing 'clientId' from Workload Config"),clientSecret:r(M.clientSecret,"Missing 'clientSecret' from Workload Config"),scope:M.scope??"",tokenLifetime:M.tokenLifetime??300,refreshThreshold:M.refreshThreshold??60,autoRefresh:M.autoRefresh!==void 0?M.autoRefresh:!0,tokenStore:M.tokenStore??new RS};else if(uS(M))Z=M;function n(){let Q=new Uint8Array(16);return crypto.getRandomValues(Q),Array.from(Q,(G)=>G.toString(16).padStart(2,"0")).join("")}function E(Q){let G;if(typeof Q==="string")G=btoa(Q);else G=btoa(String.fromCharCode(...Q));return G.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function w(Q){let G=Q.replace(/-/g,"+").replace(/_/g,"/");while(G.length%4)G+="=";return atob(G)}function q(Q){if(Q.startsWith("RS"))return{name:"RSASSA-PKCS1-v1_5",hash:Q==="RS256"?"SHA-256":Q==="RS384"?"SHA-384":"SHA-512"};else if(Q.startsWith("ES"))return{name:"ECDSA",namedCurve:Q==="ES256"?"P-256":Q==="ES384"?"P-384":"P-521",hash:Q==="ES256"?"SHA-256":Q==="ES384"?"SHA-384":"SHA-512"};throw Error(`Unsupported algorithm: ${Q}`)}async function V(Q,G){let N=Q.replace(/-----BEGIN PRIVATE KEY-----/,"").replace(/-----END PRIVATE KEY-----/,"").replace(/\s/g,""),j=Uint8Array.from(atob(N),(I)=>I.charCodeAt(0)),B=q(G);return crypto.subtle.importKey("pkcs8",j,B,!1,["sign"])}async function k(Q,G,N){let j=await V(G,N),I=new TextEncoder().encode(Q),H=q(N),_=await crypto.subtle.sign(H,j,I);return E(new Uint8Array(_))}async function g(Q,G=3,N=1000,j=30000){let B=Error("Placeholder Error");for(let I=0;I<=G;I++)try{return await Q()}catch(H){if(B=H instanceof Error?H:Error(String(H)),B.message.includes("400")||B.message.includes("401")||B.message.includes("403")||B.message.includes("404"))throw B;if(I<G){let _=Math.min(N*2**I,j),Y=Math.random()*_*0.1;await new Promise((F)=>setTimeout(F,_+Y))}}throw B}async function t(Q){if(!l(Z))throw Error("generateJWTAssertion is only available in JWT Bearer Grant mode");let G=Z,N=Math.floor(Date.now()/1000),j={iss:G.workloadId,sub:G.workloadId,aud:G.audience??"",exp:N+G.tokenLifetime,iat:N,jti:n(),scope:Q??G.scope},B={alg:G.algorithm,typ:"JWT",kid:G.keyId},I=E(JSON.stringify(B)),H=E(JSON.stringify(j)),_=`${I}.${H}`,Y=await k(_,G.privateKey,G.algorithm);return`${_}.${Y}`}async function s(Q){if(!l(Z))throw Error("generateJWTAssertion is only available in JWT Bearer Grant mode");let G=Z;return g(async()=>{let N=G.idpTokenUrl,j=await t(Q),B=new URLSearchParams;if(B.append("grant_type","urn:ietf:params:oauth:grant-type:jwt-bearer"),B.append("assertion",j),Q)B.append("scope",Q);let I=await fetch(N,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:B.toString()}),H=await I.json();if(!I.ok)throw L.error("Token acquisition error:",H),Error(`Token acquisition failed: ${H.error||I.statusText} - ${H.error_description||""}`.trim());let _=await S.tokenResponse["~standard"].validate(H);if(_.issues)throw L.error("Token response validation failed:",_.issues),Error(`Token response validation failed: ${_.issues.map((Y)=>Y.message).join("; ")}`);if(G.tokenStore){let Y=new Date(Date.now()+(_.value.expires_in??300)*1000),F={workload_id:G.workloadId,access_token:_.value.access_token,token_type:_.value.token_type,scope:_.value.scope,expires_at:Y,created_at:new Date,refresh_token:_.value.refresh_token};await G.tokenStore.set(F)}return _.value})}async function p(Q){if(!e(Z))throw Error("acquireTokenClientCredentials is only available in OAuth2 Client Credentials mode");let G=Z;return g(async()=>{let N=G.idpTokenUrl,j=new URLSearchParams;if(j.append("grant_type","client_credentials"),j.append("client_id",G.clientId),j.append("client_secret",G.clientSecret),Q)j.append("scope",Q);let B=await fetch(N,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:j.toString()}),I=await B.json();if(!B.ok)throw L.error("Token acquisition error:",I),Error(`Token acquisition failed: ${I.error||B.statusText} - ${I.error_description||""}`.trim());let H=await S.tokenResponse["~standard"].validate(I);if(H.issues)throw L.error("Token response validation failed:",H.issues),Error(`Token response validation failed: ${H.issues.map((_)=>_.message).join("; ")}`);if(G.tokenStore){let _=new Date(Date.now()+(H.value.expires_in??300)*1000),Y={workload_id:G.clientId,access_token:H.value.access_token,token_type:H.value.token_type,scope:H.value.scope,expires_at:_,created_at:new Date,refresh_token:H.value.refresh_token};await G.tokenStore.set(Y)}return H.value})}async function DS(Q){if(!l(Z)&&!e(Z)){let B=Z;throw Error(`Acquiring tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode. Current config: hasClientId=${!!B.clientId}, hasClientSecret=${!!B.clientSecret}, hasWorkloadId=${!!B.workloadId}, hasPrivateKey=${!!B.privateKey}, hasJwksUri=${!!B.jwksUri}`)}let G=Z;Q=Q??G.scope;let N=l(Z)?Z.workloadId:Z.clientId;if(G.tokenStore){let B=await G.tokenStore.get(N);if(B){let I=Date.now(),H=B.expires_at.getTime(),_=G.refreshThreshold*1000;if(I+_<H)return B.access_token;if(G.autoRefresh)try{return(l(Z)?await s(Q):await p(Q)).access_token}catch(Y){if(I<H)return L.warn("Token refresh failed, using cached token:",Y),B.access_token;throw Y}}}return(l(Z)?await s(Q):await p(Q)).access_token}async function T(Q){if(!l(Z)&&!e(Z))throw Error("Refreshing tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode");let G=Z;return Q=Q??G.scope,l(G)?await s(Q):await p(Q)}async function C(Q){if(!l(Z)&&!e(Z))throw Error("Revoking tokens is only available in JWT Bearer Grant or OAuth2 Client Credentials mode");let G=Z;try{if(!Z.revocationEndpoint)return;let N=new URLSearchParams;if(N.append("token",Q),N.append("token_type_hint","access_token"),l(Z)){let B=Z;N.append("client_id",B.workloadId)}else if(e(Z)){let B=Z;N.append("client_id",B.clientId),N.append("client_secret",B.clientSecret)}let j=await fetch(Z.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:N.toString()});if(!j.ok)L.warn("Token revocation failed:",j.status,j.statusText);else L.info("Token revoked successfully");if(Z.tokenStore){let B;if(l(Z))B=Z.workloadId;else if(e(Z))B=Z.clientId;else return;await Z.tokenStore.delete(B)}}catch(N){L.warn("Error revoking token:",N)}}async function x(){if(!Z?.jwksUri)throw Error("No JWKS URI configured in Workload Config");let Q=Z.jwksUri,G=DL.get(Q);if(G)return G;return g(async()=>{let N=await fetch(Q);if(!N.ok)throw Error("Failed to fetch JWKS");let j=await N.json();return DL.set(Q,j),j})}async function v(Q){let N=(await x()).keys.find((I)=>I.kid===Q);if(!N)throw Error("Public key not found");let j=l(Z)?Z.algorithm:"RS256",B=q(N.alg||j);return crypto.subtle.importKey("jwk",N,B,!1,["verify"])}async function b(Q){try{let G=Q.split(".");if(G.length!==3)throw Error("Invalid JWT");let N=JSON.parse(w(G[0])),j=JSON.parse(w(G[1])),B=await v(N.kid),I=G[2],_=new TextEncoder().encode(`${G[0]}.${G[1]}`),Y=Uint8Array.from(w(I),(d)=>d.charCodeAt(0)),F=q(N.alg);if(!await crypto.subtle.verify(F,B,Y,_))throw Error("Invalid JWT signature");let O=await S.jwtAssertionClaims["~standard"].validate(j);if(O.issues)throw L.error("JWT claims validation failed:",O.issues),Error(`JWT claims validation failed: ${O.issues.map((d)=>d.message).join("; ")}`);return O.value}catch(G){throw L.error("Error verifying JWT:",G),G}}async function u(Q){if(!l(Z)&&!e(Z)&&!uS(Z))throw Error("Validating tokens is only available in JWT Bearer Grant, OAuth2 Client Credentials, or Server-Only mode");try{let G=await b(Q),N=Math.floor(Date.now()/1000);if(G.exp&&G.exp<N)return{valid:!1,error:"Token expired"};if(l(Z)){if(Z.audience&&G.aud!==Z.audience)return{valid:!1,error:"Invalid audience"}}else if(e(Z)){if(Z.issuer&&G.iss!==Z.issuer)return{valid:!1,error:"Invalid issuer"};if(Z.audience&&G.aud!==Z.audience)return{valid:!1,error:"Invalid audience"}}else{let j=Z;if(j.issuer&&G.iss!==j.issuer)return{valid:!1,error:"Invalid issuer"}}return{valid:!0,claims:G,expiresAt:G.exp?new Date(G.exp*1000):void 0}}catch(G){return{valid:!1,error:G instanceof Error?G.message:String(G)}}}async function W(Q){let G=Q.headers.get("Authorization");if(!G||!G.startsWith("Bearer "))return;let N=G.substring(7),j=await u(N);if(!j.valid||!j.claims)return;return{workloadId:j.claims.sub,clientId:typeof j.claims.client_id==="string"?j.claims.client_id:void 0,scope:j.claims.scope,claims:j.claims}}async function m(Q){if(!Z)throw Error("Enterprise Standard Workload Manager not initialized");let G=new URL(Q.url).pathname,N=(Y)=>{if(!Y)return;try{return new URL(Y).pathname}catch{return Y.startsWith("/")?Y:`/${Y}`}},j=Z._handlerTokenUrl;if(N(j||Z.tokenUrl)===G&&Q.method==="GET")try{let F=new URL(Q.url).searchParams.get("scope")||void 0,A=await DS(F);return new Response(JSON.stringify({access_token:A,token_type:"Bearer"}),{headers:[["Content-Type","application/json"]]})}catch(Y){return L.error("Error in token endpoint:",Y),new Response(JSON.stringify({error:Y instanceof Error?Y.message:"Internal server error"}),{status:500,headers:[["Content-Type","application/json"]]})}if(N(Z.validateUrl)===G&&Q.method==="POST"){let Y=Q.headers.get("Authorization");if(!Y||!Y.startsWith("Bearer "))return new Response(JSON.stringify({valid:!1,error:"Missing Authorization header"}),{status:401,headers:[["Content-Type","application/json"]]});let F=Y.substring(7),A=await u(F);return new Response(JSON.stringify(A),{status:A.valid?200:401,headers:[["Content-Type","application/json"]]})}if(N(Z.jwksUrl)===G&&Q.method==="GET"){let Y=await x();return new Response(JSON.stringify(Y),{headers:[["Content-Type","application/json"]]})}if(N(Z.refreshUrl)===G&&Q.method==="POST")try{let Y=await T();return new Response(JSON.stringify(Y),{headers:[["Content-Type","application/json"]]})}catch(Y){return L.error("Error in refresh endpoint:",Y),new Response(JSON.stringify({error:Y instanceof Error?Y.message:"Internal server error"}),{status:500,headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...Z,getToken:DS,refreshToken:T,generateJWTAssertion:t,revokeToken:C,validateToken:u,getWorkloadIdentity:W,parseJWT:b,handler:m}}function hS(S){return S=S??"Workload authentication unavailable",new Response(JSON.stringify({error:S}),{status:503,statusText:S,headers:{"Content-Type":"application/json"}})}var VS="EnterpriseStandard instance is required. Create one with enterpriseStandard(source, config) and pass it to this function.",dL="EnterpriseStandard or Workload instance is required. Create an ES with enterpriseStandard(source, config) or pass a Workload instance.";async function cL(S,L){r(L,VS);let $=L.workload;if(!$)return;return $.getWorkloadIdentity(S)}async function nL(S,L,$){r(L,VS);let R=L.workload;if(!R)throw hS();return R.getToken($,{client:S})}async function fL(S,L){r(L,dL);let $="validateToken"in L&&typeof L.validateToken==="function"?L:L.workload;if(!$)return{valid:!1,error:"Workload authentication unavailable"};let R=S.headers.get("Authorization");if(!R||!R.startsWith("Bearer "))return{valid:!1,error:"Missing or invalid Authorization header"};let U=R.substring(7);return $.validateToken(U)}async function gL(S,L){r(L,VS);let $=L.workload;if(!$)throw hS();return $.revokeToken(S)}async function sL(S,L){r(L,VS);let $=L.workload;if(!$)throw hS();return $.handler(S)}export*from"@enterprisestandard/core";import{InMemoryTenantStore as TR,parseTenantRequest as AR,sendTenantWebhook as VR,TenantRequestError as OR,tenant as WR}from"@enterprisestandard/core";import{callback as wR,ciam as xR,getCIAMUser as yR,getRequiredSSOorCIAMUser as kR,getSSOorCIAMUser as vR,getSSOorCIAMUser as bR,getSSOUser as mR,iam as CR,initiateLogin as uR,logout as hR,logoutBackChannel as dR,sso as cR,verifyUser as nR}from"@enterprisestandard/core/server";import{setActiveSession as lL}from"@enterprisestandard/core";async function pL(S,L){let $=[];for(let[R,U]of L.entries()){if(!U.sso)continue;try{let D=await U.sso.getUser(S);if(!D)continue;$.push({clientId:R,user:D,valid:!0,expiresAt:D.sso?.expires})}catch{}}return $}async function iL(S,L,$,R={}){let U=$.get(L);if(!U?.sso)return new Response(JSON.stringify({error:"Unknown tenant session"}),{status:404,headers:{"Content-Type":"application/json"}});if(await U.sso.getUser(S)){let M=lL(L,{cookieName:R.activeSessionCookieName,path:R.cookiePath,secure:R.cookieSecure,sameSite:R.cookieSameSite,maxAge:R.cookieMaxAge});return new Response(JSON.stringify({success:!0}),{status:200,headers:{"Content-Type":"application/json","Set-Cookie":M}})}let X=R.loginUrl??U.sso.loginUrl;if(!X)return new Response(JSON.stringify({error:"Session expired"}),{status:401,headers:{"Content-Type":"application/json"}});let J=new URL(X,S.url);if(!J.searchParams.has("clientId"))J.searchParams.set("clientId",L);return new Response(null,{status:302,headers:{Location:J.toString()}})}async function tL(S,L,$){await S.putSecret(L,$)}function rL(S){let{type:L,...$}=S;return ZS({type:"vault",...$})}function a(S){if(!S)return;try{return new URL(S,"http://dummy").pathname}catch{return S.startsWith("/")?S:`/${S}`}}function $$(S,L){if(S?.sso?.redirectUri&&L.sso?.redirectUri){let $=a(S.sso.redirectUri),R=a(L.sso.redirectUri);if($!==R)throw Error(`redirectUri path in framework config must match ConfigSource redirectUri path. ConfigSource path: ${$}, framework path: ${R}`)}}function cS(S){let L={};if(!S)return L;for(let[$,R]of Object.entries(S))if(R.type==="lfv")L[$]=R;return L}function R$(S){return S[wS]}function U$(S,L){let $=cS(S.secrets),R=a(L.deliveryEndpoint),U=a(L.eventsEndpoint),D=a(L.path);for(let X of Object.values($)){if(a(X.deliveryEndpoint)!==R)continue;if(a(X.eventsEndpoint)!==U)continue;let J=X.path?a(X.path):void 0;if(D&&J&&D!==J)continue;return!0}return!1}function D$(S,L){let $=R$(L);if(!$)return S;if(U$(S,$))return S;let R={type:"lfv",path:$.path,lfvServerUrl:$.lfvServerUrl,clientId:$.clientId,signature:$.signature,deliveryTimeout:$.deliveryTimeout,retryInterval:$.retryInterval,warnInterval:$.warnInterval,deliveryEndpoint:$.deliveryEndpoint,eventsEndpoint:$.eventsEndpoint,verifyPublicKey:$.verifyPublicKey},U=S.secrets??{},D="LFV_BOOTSTRAP",X=1;while(D in U)X+=1,D=`LFV_BOOTSTRAP_${X}`;return{...S,secrets:{...U,[D]:R}}}function _$(S,L){let $=cS(S.secrets),R=cS(L.secrets);for(let[U,D]of Object.entries(R)){let X=$[U];if(!X)continue;let J=a(X.deliveryEndpoint),M=a(D.deliveryEndpoint);if(J&&M&&J!==M)throw Error(`LFV deliveryEndpoint path for secrets source "${U}" in framework config must match ConfigSource path. ConfigSource path: ${J}, framework path: ${M}`);let Z=a(X.eventsEndpoint),z=a(D.eventsEndpoint);if(Z&&z&&Z!==z)throw Error(`LFV eventsEndpoint path for secrets source "${U}" in framework config must match ConfigSource path. ConfigSource path: ${Z}, framework path: ${z}`)}}function YL(S,L){if(L===void 0)return!1;return JSON.stringify(S)===JSON.stringify(L)}function ZL(S,L,$,R,U){let D={logger:R,tenantId:S.tenantId,config:S,handler:async()=>new Response("Not Found",{status:404})};return D.workload=US($.workload,R,S?.workload,L.workload),D.secrets=CS($.secrets,R,S?.secrets,L?.secrets),D.sso=L$($.sso,R,S?.sso,L.sso),D.iam=S$($.iam,R,D.workload,S?.iam,L.iam),D.tenants=eL($.tenant,R,S?.tenant,L.tenant),D.ciam=oL($.ciam,R,S?.ciam,L.ciam,D.workload),D.handler=async(X)=>LL(X,D,U?.routing),D}function Y$(S,L,$,R,U,D){$$(L,$),_$(L,$);let X=ZL(L,$,R,U,D);S.tenantId=L.tenantId,S.config=L,S.logger=U,S.workload=X.workload,S.secrets=X.secrets,S.sso=X.sso,S.iam=X.iam,S.tenants=X.tenants,S.ciam=X.ciam,S.handler=X.handler}function X$(S,L,$,R){let U=S,D=L;if(R?.beforeChange){let X=R.beforeChange(S,L,$);if(X?.config!==void 0)U=X.config;if(X?.frameworkConfig!==void 0)D=X.frameworkConfig}return{effectiveRemoteConfig:U,effectiveFrameworkConfig:D}}function XL(S){return!!S&&typeof S==="object"&&typeof S.load==="function"}function OS(S){if(!S||typeof S!=="object")return!1;let L=S;return"beforeChange"in L||"afterChange"in L||"routing"in L}async function FR(S,L,$){let R,U,D,X=!1;if(XL(S))R=S,U=OS(L)?void 0:L,D=OS(L)?L:$;else X=!0,R=vS(),U=S,D=OS(L)?L:$;if(XL(S)&&OS(L)&&$)D=$;if(X&&!process.env.ES_CONFIG_TYPE)(U?.logger??dS).warn?.("enterpriseStandard() defaulted to envConfig() with no ES_CONFIG_TYPE set. Falling back to dev config source.");if(X&&!U)U=TS();let J=rS(U,D);U=J.config,D=J.options;let M=D$(U??{},R),Z=M.validators||aL(),z=M.logger||dS,K,P=M,y=ZL({},M,Z,z,D);function n(E){if(K!==void 0&&YL(E,K))return;let w=K,{effectiveRemoteConfig:q,effectiveFrameworkConfig:V}=X$(E,P,K,D);if(K!==void 0&&YL(q,K)&&V===P)return;let k=V.logger||dS;Y$(y,q,V,Z,k,D),K=q,P=V,M=V,Z=V.validators??Z,D?.afterChange?.(y,q,P,w)}if(y.reload=async()=>{let E=await R.load();n(E)},y.reconfigure=async(E)=>{if(E!=null)M={...M,...E},P=M,Z=M.validators??Z;let w=await R.load();n(w)},R.subscribe)R.subscribe((E)=>n(E));return R.load().then((E)=>n(E),(E)=>z.warn?.("ConfigSource initial load failed",E)),y}export{tL as writeEsaConfigToVault,sL as workloadHandler,US as workload,nR as verifyUser,BS as vaultConfig,fL as validateWorkloadToken,WR as tenantManagement,iL as switchSession,cR as sso,VR as sendTenantWebhook,CS as secrets,gL as revokeWorkloadToken,AR as parseTenantRequest,rL as openbaoVault,dR as logoutBackChannel,hR as logout,yS as localFileConfig,xS as lfvConfig,uR as initiateLogin,CR as iam,nL as getWorkloadToken,cL as getWorkload,bR as getUser,vR as getSSOorCIAMUser,mR as getSSOUser,kR as getRequiredSSOorCIAMUser,yR as getCIAMUser,HS as gcpConfig,vS as envConfig,FR as enterpriseStandard,TS as dynamicConfig,pL as discoverSessions,IS as devConfig,xR as ciam,wR as callback,NS as azureConfig,MS as awsConfig,OL as adaptiveFramework,OR as TenantRequestError,RS as InMemoryWorkloadTokenStore,jS as InMemoryUserStore,TR as InMemoryTenantStore,qS as InMemorySessionStore,FS as InMemoryMagicLinkStore,JS as InMemoryGroupStore};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enterprisestandard/server",
|
|
3
|
-
"version": "0.0.8
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Enterprise Standard Server (Node/server-only)",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "enterprisestandard",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"./package.json": "./package.json"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@enterprisestandard/core": "0.0.8
|
|
24
|
+
"@enterprisestandard/core": "^0.0.8"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@enterprisestandard/zod": "0.0.8
|
|
28
|
-
"@enterprisestandard/valibot": "0.0.8
|
|
27
|
+
"@enterprisestandard/zod": "^0.0.8",
|
|
28
|
+
"@enterprisestandard/valibot": "^0.0.8"
|
|
29
29
|
}
|
|
30
30
|
}
|