corsair 0.1.121 → 0.1.122
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/{chunk-56G5KUMM.js → chunk-H66F2BLQ.js} +2 -2
- package/dist/{connect-L3R6F7WA.js → connect-T3HADHZ2.js} +1 -1
- package/dist/core.js +1 -1
- package/dist/hub/tunnel/run-tunnel.js +4 -4
- package/dist/hub.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{loop-FAJAJSPN.js → loop-HRJJRT5L.js} +1 -1
- package/dist/oauth.js +1 -1
- package/dist/{setup-EMCKALPS.js → setup-QTI7NP2N.js} +1 -1
- package/dist/{setup-introspect-NCOKP62I.js → setup-introspect-AGBGQAOZ.js} +1 -1
- package/dist/setup.js +1 -1
- package/dist/tunnel.js +1 -1
- package/package.json +4 -4
|
@@ -6,7 +6,7 @@ import{a as we,b as qt,c as Kt}from"./chunk-3TC2WIUS.js";import{a as Ao,b as Ce,
|
|
|
6
6
|
window.parent.postMessage(message, targetOrigin);
|
|
7
7
|
}
|
|
8
8
|
})();
|
|
9
|
-
</script></body></html>`}var ya=new Set(["localhost","127.0.0.1","[::1]","::1"]);function Xt(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ya.has(n)}catch{return!1}}function mn(e){return e==="development"?"browser":"server"}function No(e){return mn(e)==="browser"}function Lo(e){return Xt(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as ka}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as ma,randomBytes as ha,timingSafeEqual as ba}from"crypto";function le(){return ha(16).toString("base64url")}function hn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return ma("sha256",t).update(e).digest("base64url")}function ie(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=hn(o,t);try{if(!ba(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function Kn(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=hn(i,n);return`${i}.${s}`}function bn(e,n,t){let r=Math.floor(Date.now()/1e3);return Kn(e,n,r+Math.floor(t/1e3))}function He(e){return decodeURIComponent(e)}function Qt(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function $o(e){let n=e.trim();return n.length>0?n:null}function Ze(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Ge(e,n){if(!$o(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??ka(16).toString("base64url"),iat:t,exp:t+Math.floor(Te/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=hn(o,n);return`${o}.${i}`}function Pe(e,n){return $o(n)?ie(e,n):null}function Ca(e){let n=Yt(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function er(e){let n=Ge(Ca(e),e.signingSecret);return Ze(e.deliveryUrl,n)}function Wo(e){if(mn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=wa(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:er(r)}}var kn="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}};function Zn(e){let n=(e.apiUrl?.trim()||kn).replace(/\/$/,""),t=e.projectApiKey.trim(),r=e.signingSecret.trim();if(!t||!r)throw new Error("Hub config requires non-empty projectApiKey and signingSecret");return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function va(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!va(n))throw new de;return n}function jo(e){return e.replace(/\/$/,"")}function Gn(e){return e.oauthCallbackUrl?jo(e.oauthCallbackUrl.trim()):`${jo(e.apiUrl)}/oauth/callback`}function ze(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as qo,createDecipheriv as Ko,randomBytes as zn,scrypt as Ta}from"crypto";import{promisify as Pa}from"util";var Zo=Pa(Ta),Jn="aes-256-gcm",Go=12,Vn=16,Aa=16,wn=32;function pe(){return zn(wn).toString("base64")}async function ge(e,n){let t=zn(Aa),r=await Zo(n,t,wn),o=zn(Go),i=qo(Jn,r,o,{authTagLength:Vn}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Zo(n,s,wn),d=Ko(Jn,c,a,{authTagLength:Vn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function nr(e,n){let t=Buffer.from(n,"base64"),r=zn(Go),o=qo(Jn,t,r,{authTagLength:Vn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function Cn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Ko(Jn,i,s,{authTagLength:Vn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function Ae(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=nr(o,n);return t}function fe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Cn(o,n);return t}function vn(e,n,t){let r=fe(e,n);return Ae(r,t)}function zo(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var tr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...L[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:tr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let k=await u.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await u.getIntegration(),b=await c(),C=k.config;return!C||Object.keys(C).length===0?{}:fe(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await c(),C;try{C=await d()}catch(E){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,E),C={}}let T={...C};for(let[E,M]of Object.entries(k))M===null?delete T[E]:T[E]=M;let D=Ae(T,b);await u.updateIntegration({config:D})};return{get_dek:c,issue_new_dek:async()=>{let k=await u.getIntegration(),b=pe(),C={};if(k.dek){let D=await Y(k.dek,r),E=k.config;E&&Object.keys(E).length>0&&(C=vn(E,D,b))}let T=await ge(b,r);return await u.updateIntegration({config:C,dek:T}),l=b,b},...zo(d,g,s)}}function H(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...L[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:A.id,config:tr(A.config),dek:A.dek??null},c}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:tr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},T=Promise.resolve(),D=w=>{let A=T.then(()=>E(w));return T=A.catch(()=>{}),A},E=async w=>{let A=await h(),R;try{R=await b()}catch(S){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,S),R={}}let z={...R};for(let[S,te]of Object.entries(w))te===null?delete z[S]:z[S]=te;let ce=Ae(z,A);await p.updateAccount({config:ce})},M={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=pe(),R={};if(w.dek){let ce=await Y(w.dek,o),S=w.config;S&&Object.keys(S).length>0&&(R=vn(S,ce,A))}let z=await ge(A,o);return await p.updateAccount({config:R,dek:z}),g=A,A},...zo(b,D,u)};return n==="oauth_2"&&(M.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),M}async function Jo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=pe(),i=await ge(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Vo(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=pe(),a=await ge(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var Ra=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Re(e){return Ra.has(e)}function xa(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Ia(e){return!Re(e)}function Sa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function _a(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ea(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Sa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function Yo(e,n){if(!e)return!1;let t=G(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Da(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Oa(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Ma(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:Ea(n,t),fields:t,missingRequiredFields:r}}async function Be(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],u=U({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=H({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=Da(n,r),d=Oa(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:xa(r,g),configured:await Yo(u,g)});for(let g of d)p.push({name:g,level:"account",required:Ia(g),configured:await Yo(l,g)});if(_a(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ma(n.id,r,p)}async function Tn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Be(e,s,r);a&&i.push(a)}return i}function Yn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Xo=Symbol.for("corsair:internal"),Qo=new WeakMap,ei=new WeakMap;function Ha(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ba(e){if(e.database){let t=Qo.get(e.database);return t||(t=new Map,Qo.set(e.database,t)),t}let n=ei.get(e);return n||(n=new Map,ei.set(e,n)),n}function Fa(e){return e.multiTenancy?{withTenant:()=>({}),[Xo]:e}:{[Xo]:e}}async function Je(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ba(e),o=Ha(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-EMCKALPS.js");await a(Fa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Pn from"crypto";function xe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function rr(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function Ve(e,n){let t=Pn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var or=600*1e3;function Xn(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Pn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Pn.timingSafeEqual(s,a)?null:rr(r,{maxAgeMs:or})}function ni(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function ti(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function Ye(e,n){await x({hub:e,path:"/connections/report",body:ni(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Ua(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof de)return}}async function Na(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Be(n,e.plugin,r);o&&oi(e.hub,ti({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function ri(e,n){Ua(e,n)}function oi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function An(e){Na(e).catch(()=>{})}async function ye(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Be(t,n.plugin,n.tenantId);o&&ri(e,ti({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function Qn(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var ii=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function La(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function $a(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=ii(n.config),o={};Object.keys(r).length>0&&(o=fe(r,t)),o[e.link.linkType]=e.link.externalId;let i=Ae(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function Xe(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await La({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=H({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await $a({database:n,kek:t,accountId:u,link:i})}async function ir(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Y(a.dek,t),c=ii(a.config)[o];if(!c)continue;if(Cn(c,u)===i)return a}catch{continue}return null}async function et(e){return(await ir(e))?.tenant_id??null}async function si(e){return et({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as ai from"querystring";function Fe(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${ai.stringify(i)}`}async function ui(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function Qe(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await ui(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await ye(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var j=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ci(e){let n=e.oauthConfig;if(!n)throw new j("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Wa(e,n,t,r){let o=Eo(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=pe(),u=await ge(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function sr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=W(s,n,p=>new j("plugin_not_found",p)),u=ci(a),c=await U({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Fe({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=Ve(xe(n,r),s.kek);return{url:Fe({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function ja(e,n){return{...n??{},...e}}async function Rn(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new j("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=Xn(r,i.kek);if(!h)throw new j("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new j("no_database","No database configured on corsair instance");let u=W(i,s,h=>new j("plugin_not_found",h)),l=ci(u),c=U({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new j("credentials_not_configured",`Credentials not configured for '${s}'`);await Wa(i.database,s,a,i.kek);let g=await nt(t,d,p,l,o);if(!g.access_token)throw new j("no_access_token",`No access_token returned from ${l.providerName}`);let f=H({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await ye(e,{plugin:u,tenantId:a}).catch(()=>{});try{let h=ja(g,n.callbackParams),k=await Qn(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await Xe({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&Ye(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(u.subscribe)try{await Qe(e,u,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function qa(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??Qe,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let u=t.plugins.find(c=>c.id===a.integrationName);if(!u?.subscribe)continue;let l=`${u.id}/${a.tenantId}`;try{let c=I(u)??"oauth_2",d=H({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function li(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return qa({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Ka(e,n={}){let t=!1,r=()=>{t||(t=!0,li(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function di(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await tt(e,{silent:!0})}async function en(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Je(t,n)}var Za=Symbol.for("corsair:internal"),Ga=new Set(["access_token","refresh_token","expires_at","scope"]);function za(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Ja(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Ga.has(t)):n.filter(t=>!Re(t))}function pi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Va(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Ya(e){return{[Za]:pi(e)}}async function rt(e,n,t={}){let r=Gn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=pi(e),a=Ya(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=za(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Be(s,u,n),g=Un(u,l),f=Ja(l,g),h={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),c==="oauth"){let b=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await sr(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${u.id}`)}}o.push(h)}return o}async function Hp(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return rt({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function gi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Je(e.internalConfig??Va(e),n)}async function fi(e,n){await en(e,n)}async function yi(e,n){let t=ze(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Ln})}async function ar(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await gi(t,n.tenantId);let r=await rt(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return yi(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ot(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await fi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,u=await rt(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(u.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return yi(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function it(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await Xa(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function Xa(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-NCOKP62I.js"),{postHubConnectSession:i}=await import("./connect-L3R6F7WA.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function nn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var X=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function Qa(e){let n=e.oauthConfig;if(!n)throw new X("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function ur(e,n){let t=v(e,()=>new X("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new X("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new X("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=Xn(n,t.kek);if(!o)throw new X("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=W(t,i,p=>new X("plugin_not_found",p)),u=Qa(a),c=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new X("client_id_not_configured",`client_id not configured for '${i}'`);let d=Fe({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as nu}from"async_hooks";import{randomBytes as tu}from"crypto";import{v4 as ru}from"uuid";async function st(e,n){let t=ze(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Wn})}function at(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var cr="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function dr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function mi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function lr(e){return at(e)}async function pr(e,n){if(dr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?mi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await st(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:eu(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function eu(e){try{return JSON.parse(e)}catch{return e}}async function ut(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await pr(e,n);return{...n,approvalUrl:r}}async function gr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await pr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return dr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):lr(g):cr:r?g?lr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:cr}var tn=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var bi=new nu,ct=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function fr(e){return bi.run(!0,e)}function ki(){return bi.getStore()===!0}function yr(e,n){if(ki()&&n!=="read")throw new ct(e,n)}var ou={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function iu(e,n,t){return t!==void 0?t:ou[n][e]}function mr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function wi(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function hi(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Ci(e){let n=iu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
9
|
+
</script></body></html>`}var ya=new Set(["localhost","127.0.0.1","[::1]","::1"]);function Xt(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ya.has(n)}catch{return!1}}function mn(e){return e==="development"?"browser":"server"}function No(e){return mn(e)==="browser"}function Lo(e){return Xt(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as ka}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as ma,randomBytes as ha,timingSafeEqual as ba}from"crypto";function le(){return ha(16).toString("base64url")}function hn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return ma("sha256",t).update(e).digest("base64url")}function ie(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=hn(o,t);try{if(!ba(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function Kn(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=hn(i,n);return`${i}.${s}`}function bn(e,n,t){let r=Math.floor(Date.now()/1e3);return Kn(e,n,r+Math.floor(t/1e3))}function He(e){return decodeURIComponent(e)}function Qt(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function $o(e){let n=e.trim();return n.length>0?n:null}function Ze(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Ge(e,n){if(!$o(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??ka(16).toString("base64url"),iat:t,exp:t+Math.floor(Te/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=hn(o,n);return`${o}.${i}`}function Pe(e,n){return $o(n)?ie(e,n):null}function Ca(e){let n=Yt(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function er(e){let n=Ge(Ca(e),e.signingSecret);return Ze(e.deliveryUrl,n)}function Wo(e){if(mn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=wa(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:er(r)}}var kn="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}};function Zn(e){let n=(e.apiUrl?.trim()||kn).replace(/\/$/,""),t=e.projectApiKey.trim(),r=e.signingSecret.trim();if(!t||!r)throw new Error("Hub config requires non-empty projectApiKey and signingSecret");return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function va(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!va(n))throw new de;return n}function jo(e){return e.replace(/\/$/,"")}function Gn(e){return e.oauthCallbackUrl?jo(e.oauthCallbackUrl.trim()):`${jo(e.apiUrl)}/oauth/callback`}function ze(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as qo,createDecipheriv as Ko,randomBytes as zn,scrypt as Ta}from"crypto";import{promisify as Pa}from"util";var Zo=Pa(Ta),Jn="aes-256-gcm",Go=12,Vn=16,Aa=16,wn=32;function pe(){return zn(wn).toString("base64")}async function ge(e,n){let t=zn(Aa),r=await Zo(n,t,wn),o=zn(Go),i=qo(Jn,r,o,{authTagLength:Vn}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Zo(n,s,wn),d=Ko(Jn,c,a,{authTagLength:Vn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function nr(e,n){let t=Buffer.from(n,"base64"),r=zn(Go),o=qo(Jn,t,r,{authTagLength:Vn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function Cn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Ko(Jn,i,s,{authTagLength:Vn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function Ae(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=nr(o,n);return t}function fe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Cn(o,n);return t}function vn(e,n,t){let r=fe(e,n);return Ae(r,t)}function zo(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var tr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...L[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:tr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let k=await u.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await u.getIntegration(),b=await c(),C=k.config;return!C||Object.keys(C).length===0?{}:fe(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await c(),C;try{C=await d()}catch(E){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,E),C={}}let T={...C};for(let[E,M]of Object.entries(k))M===null?delete T[E]:T[E]=M;let D=Ae(T,b);await u.updateIntegration({config:D})};return{get_dek:c,issue_new_dek:async()=>{let k=await u.getIntegration(),b=pe(),C={};if(k.dek){let D=await Y(k.dek,r),E=k.config;E&&Object.keys(E).length>0&&(C=vn(E,D,b))}let T=await ge(b,r);return await u.updateIntegration({config:C,dek:T}),l=b,b},...zo(d,g,s)}}function H(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...L[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:A.id,config:tr(A.config),dek:A.dek??null},c}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:tr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},T=Promise.resolve(),D=w=>{let A=T.then(()=>E(w));return T=A.catch(()=>{}),A},E=async w=>{let A=await h(),R;try{R=await b()}catch(S){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,S),R={}}let z={...R};for(let[S,te]of Object.entries(w))te===null?delete z[S]:z[S]=te;let ce=Ae(z,A);await p.updateAccount({config:ce})},M={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=pe(),R={};if(w.dek){let ce=await Y(w.dek,o),S=w.config;S&&Object.keys(S).length>0&&(R=vn(S,ce,A))}let z=await ge(A,o);return await p.updateAccount({config:R,dek:z}),g=A,A},...zo(b,D,u)};return n==="oauth_2"&&(M.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),M}async function Jo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=pe(),i=await ge(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Vo(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=pe(),a=await ge(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var Ra=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Re(e){return Ra.has(e)}function xa(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Ia(e){return!Re(e)}function Sa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function _a(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ea(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Sa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function Yo(e,n){if(!e)return!1;let t=G(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Da(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Oa(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Ma(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:Ea(n,t),fields:t,missingRequiredFields:r}}async function Be(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],u=U({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=H({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=Da(n,r),d=Oa(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:xa(r,g),configured:await Yo(u,g)});for(let g of d)p.push({name:g,level:"account",required:Ia(g),configured:await Yo(l,g)});if(_a(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ma(n.id,r,p)}async function Tn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Be(e,s,r);a&&i.push(a)}return i}function Yn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Xo=Symbol.for("corsair:internal"),Qo=new WeakMap,ei=new WeakMap;function Ha(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ba(e){if(e.database){let t=Qo.get(e.database);return t||(t=new Map,Qo.set(e.database,t)),t}let n=ei.get(e);return n||(n=new Map,ei.set(e,n)),n}function Fa(e){return e.multiTenancy?{withTenant:()=>({}),[Xo]:e}:{[Xo]:e}}async function Je(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ba(e),o=Ha(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-QTI7NP2N.js");await a(Fa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Pn from"crypto";function xe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function rr(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function Ve(e,n){let t=Pn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var or=600*1e3;function Xn(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Pn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Pn.timingSafeEqual(s,a)?null:rr(r,{maxAgeMs:or})}function ni(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function ti(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function Ye(e,n){await x({hub:e,path:"/connections/report",body:ni(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Ua(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof de)return}}async function Na(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Be(n,e.plugin,r);o&&oi(e.hub,ti({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function ri(e,n){Ua(e,n)}function oi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function An(e){Na(e).catch(()=>{})}async function ye(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Be(t,n.plugin,n.tenantId);o&&ri(e,ti({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function Qn(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var ii=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function La(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function $a(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=ii(n.config),o={};Object.keys(r).length>0&&(o=fe(r,t)),o[e.link.linkType]=e.link.externalId;let i=Ae(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function Xe(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await La({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=H({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await $a({database:n,kek:t,accountId:u,link:i})}async function ir(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Y(a.dek,t),c=ii(a.config)[o];if(!c)continue;if(Cn(c,u)===i)return a}catch{continue}return null}async function et(e){return(await ir(e))?.tenant_id??null}async function si(e){return et({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as ai from"querystring";function Fe(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${ai.stringify(i)}`}async function ui(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function Qe(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await ui(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await ye(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var j=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ci(e){let n=e.oauthConfig;if(!n)throw new j("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Wa(e,n,t,r){let o=Eo(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=pe(),u=await ge(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function sr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=W(s,n,p=>new j("plugin_not_found",p)),u=ci(a),c=await U({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Fe({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=Ve(xe(n,r),s.kek);return{url:Fe({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function ja(e,n){return{...n??{},...e}}async function Rn(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new j("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=Xn(r,i.kek);if(!h)throw new j("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new j("no_database","No database configured on corsair instance");let u=W(i,s,h=>new j("plugin_not_found",h)),l=ci(u),c=U({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new j("credentials_not_configured",`Credentials not configured for '${s}'`);await Wa(i.database,s,a,i.kek);let g=await nt(t,d,p,l,o);if(!g.access_token)throw new j("no_access_token",`No access_token returned from ${l.providerName}`);let f=H({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await ye(e,{plugin:u,tenantId:a}).catch(()=>{});try{let h=ja(g,n.callbackParams),k=await Qn(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await Xe({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&Ye(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(u.subscribe)try{await Qe(e,u,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function qa(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??Qe,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let u=t.plugins.find(c=>c.id===a.integrationName);if(!u?.subscribe)continue;let l=`${u.id}/${a.tenantId}`;try{let c=I(u)??"oauth_2",d=H({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function li(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return qa({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Ka(e,n={}){let t=!1,r=()=>{t||(t=!0,li(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function di(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await tt(e,{silent:!0})}async function en(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Je(t,n)}var Za=Symbol.for("corsair:internal"),Ga=new Set(["access_token","refresh_token","expires_at","scope"]);function za(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Ja(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Ga.has(t)):n.filter(t=>!Re(t))}function pi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Va(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Ya(e){return{[Za]:pi(e)}}async function rt(e,n,t={}){let r=Gn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=pi(e),a=Ya(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=za(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Be(s,u,n),g=Un(u,l),f=Ja(l,g),h={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),c==="oauth"){let b=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await sr(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${u.id}`)}}o.push(h)}return o}async function Hp(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return rt({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function gi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Je(e.internalConfig??Va(e),n)}async function fi(e,n){await en(e,n)}async function yi(e,n){let t=ze(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Ln})}async function ar(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await gi(t,n.tenantId);let r=await rt(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return yi(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ot(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await fi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,u=await rt(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(u.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return yi(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function it(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await Xa(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function Xa(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-AGBGQAOZ.js"),{postHubConnectSession:i}=await import("./connect-T3HADHZ2.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function nn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var X=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function Qa(e){let n=e.oauthConfig;if(!n)throw new X("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function ur(e,n){let t=v(e,()=>new X("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new X("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new X("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=Xn(n,t.kek);if(!o)throw new X("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=W(t,i,p=>new X("plugin_not_found",p)),u=Qa(a),c=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new X("client_id_not_configured",`client_id not configured for '${i}'`);let d=Fe({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as nu}from"async_hooks";import{randomBytes as tu}from"crypto";import{v4 as ru}from"uuid";async function st(e,n){let t=ze(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Wn})}function at(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var cr="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function dr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function mi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function lr(e){return at(e)}async function pr(e,n){if(dr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?mi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await st(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:eu(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function eu(e){try{return JSON.parse(e)}catch{return e}}async function ut(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await pr(e,n);return{...n,approvalUrl:r}}async function gr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await pr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return dr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):lr(g):cr:r?g?lr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:cr}var tn=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var bi=new nu,ct=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function fr(e){return bi.run(!0,e)}function ki(){return bi.getStore()===!0}function yr(e,n){if(ki()&&n!=="read")throw new ct(e,n)}var ou={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function iu(e,n,t){return t!==void 0?t:ou[n][e]}function mr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function wi(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function hi(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Ci(e){let n=iu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
10
|
Action: ${r}`,`
|
|
11
11
|
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
12
|
Action: ${r}`,`
|
|
@@ -59,7 +59,7 @@ ${Vs(o,d)}`),h.join(`
|
|
|
59
59
|
`)}}}return po(je(e),"Path not found. Available operations")}function qs(e){let n=e;for(;;){let t=ee(n),r=ne(t);if(mo(r)){let o=Q(t);if(!o)return n;n=o;continue}return n}}function gn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=qs(e),t=ee(n);if(ne(t)==="ZodObject"){let o=Ut(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=ee(a),l=ne(u),c=l==="ZodOptional"||l==="ZodNullable",d=qs(a),p=Nc(a);i.push({key:s,optional:c,type:Z(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:Z(n)}}function Ft(e,n=0){if(e===void 0)return"{}";if(e.kind==="inline")return e.type;if(e.kind==="object"){if(e.fields.length===0)return"{}";let t=js.repeat(n+1),r=js.repeat(n);return`{
|
|
60
60
|
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
61
|
`)}
|
|
62
|
-
${r}}`}return"unknown"}function Kc(e,n){let t=je(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(c=>c.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of t){let{shortPath:d,lookupKey:p}=qc(c,n),g=Ee(r.endpointMeta,p),f=Ee(r.endpointSchemas,p);!g&&!f||o.push({path:c,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:gn(f?.input),output:gn(f?.output)})}o.sort((c,d)=>c.path.localeCompare(d.path));let i=[],s=je(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=ko(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Ee(r.webhookSchemas,k.toLowerCase()),C=b?.response?Z(b.response):void 0;i.push({path:c,description:b?.description,payload:gn(b?.payload),responseType:C,usageExample:Vs(n,h)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=je(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=Js(l,k);if(!C)continue;let[T,D]=C,E=bo(D),M=Object.entries(E).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:c,entityName:T,filters:[{field:"entity_id",type:"string",operators:ho},...M]})}return a.sort((c,d)=>c.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as Ys}from"crypto";async function Zc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=Ys(),o=Ys(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as Gc}from"crypto";var Nt="https://graph.microsoft.com/v1.0",wo=2e4,zc=60;async function Jc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Nt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(wo)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${Nt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(wo)}).catch(()=>{})))}}catch{}let o=Gc(),i=new Date(Date.now()+zc*6e4).toISOString(),s=await fetch(`${Nt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(wo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function Xs(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Vc(e,n){let t=Xs(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function Yc(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function Qs(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ea(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Bn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function Xc(e){return Bn(e.body)}function na(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Lt(Array.isArray(r)?r:[r])}function ta(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=Lt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=na({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let u of o){let l=n[u],c=Array.isArray(l)?l[0]:l;if(!(!c||typeof c!="string"))try{let p=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Bn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return Lt([s?.validationToken])??null}function Qc(e){if(ta(e))return!0;let n=Bn(e.body??e.payload);return Qs(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Lt(e){for(let n of e){let t=ea(n);if(t)return t}}function el(e){let t=Bn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Hn=Symbol.for("corsair:internal");function ia(e){let n=e.database?Po(e.database):void 0,t=n&&e.kek?ws(e.plugins,n,e.kek):Mt(!!n,!!e.kek),r=Cs(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?Zn(e.hub):void 0},i=wi(n),s=Bs(o);if(e.multiTenancy){let l=Object.assign({withTenant:c=>{if(!c)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let d=lo(e.plugins,{database:n,tenantId:c,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign(d,{[Hn]:o})},keys:t,permissions:i,manage:s},{[Hn]:o});return ra(l,o.hub),oa(l,o.hub),l}let a=lo(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o}),u=Object.assign({},a,{keys:t,permissions:i,manage:s,[Hn]:o});return ra(u,o.hub),oa(u,o.hub),u}function ra(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-
|
|
62
|
+
${r}}`}return"unknown"}function Kc(e,n){let t=je(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(c=>c.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of t){let{shortPath:d,lookupKey:p}=qc(c,n),g=Ee(r.endpointMeta,p),f=Ee(r.endpointSchemas,p);!g&&!f||o.push({path:c,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:gn(f?.input),output:gn(f?.output)})}o.sort((c,d)=>c.path.localeCompare(d.path));let i=[],s=je(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=ko(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Ee(r.webhookSchemas,k.toLowerCase()),C=b?.response?Z(b.response):void 0;i.push({path:c,description:b?.description,payload:gn(b?.payload),responseType:C,usageExample:Vs(n,h)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=je(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=Js(l,k);if(!C)continue;let[T,D]=C,E=bo(D),M=Object.entries(E).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:c,entityName:T,filters:[{field:"entity_id",type:"string",operators:ho},...M]})}return a.sort((c,d)=>c.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as Ys}from"crypto";async function Zc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=Ys(),o=Ys(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as Gc}from"crypto";var Nt="https://graph.microsoft.com/v1.0",wo=2e4,zc=60;async function Jc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Nt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(wo)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${Nt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(wo)}).catch(()=>{})))}}catch{}let o=Gc(),i=new Date(Date.now()+zc*6e4).toISOString(),s=await fetch(`${Nt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(wo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function Xs(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Vc(e,n){let t=Xs(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function Yc(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function Qs(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ea(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Bn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function Xc(e){return Bn(e.body)}function na(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Lt(Array.isArray(r)?r:[r])}function ta(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=Lt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=na({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let u of o){let l=n[u],c=Array.isArray(l)?l[0]:l;if(!(!c||typeof c!="string"))try{let p=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Bn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return Lt([s?.validationToken])??null}function Qc(e){if(ta(e))return!0;let n=Bn(e.body??e.payload);return Qs(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Lt(e){for(let n of e){let t=ea(n);if(t)return t}}function el(e){let t=Bn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Hn=Symbol.for("corsair:internal");function ia(e){let n=e.database?Po(e.database):void 0,t=n&&e.kek?ws(e.plugins,n,e.kek):Mt(!!n,!!e.kek),r=Cs(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?Zn(e.hub):void 0},i=wi(n),s=Bs(o);if(e.multiTenancy){let l=Object.assign({withTenant:c=>{if(!c)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let d=lo(e.plugins,{database:n,tenantId:c,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign(d,{[Hn]:o})},keys:t,permissions:i,manage:s},{[Hn]:o});return ra(l,o.hub),oa(l,o.hub),l}let a=lo(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o}),u=Object.assign({},a,{keys:t,permissions:i,manage:s,[Hn]:o});return ra(u,o.hub),oa(u,o.hub),u}function ra(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-HRJJRT5L.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function nl(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var $t=globalThis.__corsairTunnels??=new Set;function oa(e,n){if(!nl(n))return;let t=n.projectApiKey;if($t.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}$t.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??qt;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>$t.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${Kt}`)}).catch(s=>{$t.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var tl={slack:{channels:{list:{}},users:{list:{}}},linear:{projects:{list:{}},issues:{list:{}},users:{list:{}}},github:{issues:{list:{}},repositories:{list:{}}},discord:{guilds:{list:{}},channels:{list:{}}},hubspot:{contacts:{getMany:{}},companies:{getMany:{}},deals:{getMany:{}}},gmail:{messages:{list:{}},labels:{list:{}},drafts:{list:{}},threads:{list:{}}},googlecalendar:{events:{getMany:{}}},googlemeet:{conferenceRecords:{list:{}}},googledrive:{files:{list:{}},folders:{list:{}},sharedDrives:{list:{}}},notion:{databases:{getManyDatabases:{}},databasePages:{getManyDatabasePages:{}},users:{getManyUsers:{}}},airtable:{bases:{getMany:{}}},todoist:{projects:{getMany:{}},tasks:{getMany:{}}},cal:{bookings:{list:{}}},zohomail:{folders:{list:{}},messages:{list:{}}}},Co=tl;async function tt(e,n){let t=[],r=n?.silent??!1,o=g=>{t.push(g),r||console.log(g)},i=g=>{t.push(g),r||console.warn(g)},s=n?.caller??"script",a=Ro(e);if(!a)throw new Error("setupCorsair: invalid corsair instance");if(!a.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let u=fl(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await hl(c,i);let d=await bl(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Cl(e,u,n.credentials,l,o,i);let p=await Tl(d,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ia({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await Pl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
63
|
`)}function vo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...L[n][t],...r])}function gl(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(a=>a.id===t);if(!o)continue;let i=I(o);if(!i)continue;let s=vo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function fl(e,n,t){let r=xo(e),o=t?.tenantId?.trim(),i=o!==void 0&&o.length>0;if(r&&t?.backfill&&!i)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(r&&gl(t?.credentials,n)&&!i)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(i&&!o)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:r,tenantIdProvided:i,tenantId:i?o:"default",provisionAccounts:!r||i}}function aa(e,n){return Ce(e)?n===0?!0:Object.values(e).every(t=>aa(t,n-1)):!1}function yl(e){return aa(e,4)}var ml={..._o};function Wt(e){if(e instanceof ul){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof pl?Wt(r):"unknown";return n}return e instanceof sl?`${Wt(e.unwrap())} | null`:e instanceof cl?`${Wt(e.unwrap())} | undefined`:e instanceof il?e.options.join(" | "):e instanceof dl?"string":e instanceof al?"number":e instanceof rl?"boolean":e instanceof ol?"date":e instanceof ll?"jsonb":"unknown"}async function hl(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(ml))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
64
|
Schema: ${JSON.stringify(Wt(i),null,2)}`)}async function bl(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=I(a),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?U({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(c&&!c.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${u}`)),!c||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!h){let k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:c.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).executeTakeFirst(),o(`[corsair:setup] Created account: ${u}`)}f=h&&H({authType:l,integrationName:u,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),h&&f&&!h.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${u}`))}s.set(u,{pluginId:u,authType:l,integration:g,account:f,integrationFields:[...L[l].integration,...d],accountFields:r?[...L[l].account,...p]:[]})}return s}function kl(e){if(!Ce(e))return;let n=e.keys;return Ce(n)?n:void 0}function wl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Cl(e,n,t,r,o,i){let s=kl(e),a=n.provisionAccounts?wl(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(b=>b.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let d=I(c);if(!d){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let p=vo(c,d,"integration"),g=vo(c,d,"account"),f=s?.[u],h=a?.[u],k=Ce(h)?h.keys:void 0;for(let[b,C]of Object.entries(l))if(C){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${u}.${b}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let T=G(f,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set integration field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${b}' on a multi-tenant instance`);let T=G(k,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set account field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${u}'.`)}}}var sa=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function vl(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let p of o){if(sa.has(p))continue;let g=G(t,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(sa.has(p))continue;let g=G(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||c.push(p)}let d=l.length===0&&c.length===0;if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...c];if(u==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
65
|
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of c){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{da as a,ea as b,fa as c}from"./chunk-
|
|
1
|
+
import{da as a,ea as b,fa as c}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$b as N,A as d,B as e,C as f,D as g,E as h,F as i,G as j,H as k,Hb as w,I as l,Ib as x,J as m,Jb as y,K as n,Kb as z,L as o,Ob as A,Pb as B,Qb as C,Rb as D,Sb as E,Tb as F,Ub as G,Vb as H,Wb as I,Xb as J,Yb as K,Zb as L,_b as M,a,ac as O,b,bb as v,bc as P,cc as Q,dc as R,ec as S,fc as T,ga as p,ja as q,ka as r,la as s,ma as t,na as u}from"./chunk-
|
|
1
|
+
import{$b as N,A as d,B as e,C as f,D as g,E as h,F as i,G as j,H as k,Hb as w,I as l,Ib as x,J as m,Jb as y,K as n,Kb as z,L as o,Ob as A,Pb as B,Qb as C,Rb as D,Sb as E,Tb as F,Ub as G,Vb as H,Wb as I,Xb as J,Yb as K,Zb as L,_b as M,a,ac as O,b,bb as v,bc as P,cc as Q,dc as R,ec as S,fc as T,ga as p,ja as q,ka as r,la as s,ma as t,na as u}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import{h as c}from"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{v as AuthMissingError,c as BASE_AUTH_FIELDS,R as CORSAIR_INTERNAL,D as MS_GRAPH_API_BASE,q as PermissionRequiredError,a as ProviderDisplayNames,r as ReadonlyForbiddenError,K as asRecord,u as assertReadonlyAllowed,H as collectPluginWebhookMatchers,m as createAccountKeyManager,S as createCorsair,l as createIntegrationKeyManager,Q as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,y as exchangeCodeForTokens,N as extractMicrosoftGraphValidationToken,P as firstString,A as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,I as getHeader,z as getOAuthAccessToken,C as googleChannelSubscribe,o as initializeAccountDEK,n as initializeIntegrationDEK,B as introspectPluginForDocs,O as isMicrosoftGraphValidationHandshake,t as isReadonlyScopeActive,w as logEvent,x as logEventFromContext,F as matchWebhookPlugin,G as matchWebhookPluginAndTenant,E as msGraphSubscribe,k as reEncryptConfig,L as readBodyRecord,M as readQueryParam,p as resolveConnectLink,s as runReadonly,T as shouldStartTunnel,J as toExternalId};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as
|
|
2
|
-
`)}import K from"http";var
|
|
3
|
-
`).find(n=>
|
|
4
|
-
`).filter(n=>n.trim()!=="").at(-1)?.trim()??""}async function
|
|
1
|
+
import{a as I,b as L,c as w,f as O}from"../../chunk-3TC2WIUS.js";import"../../chunk-SOY77BN4.js";import{spawn as X}from"child_process";import{mkdtempSync as rr,rmSync as er,writeFileSync as G}from"fs";import{tmpdir as tr}from"os";import{join as S}from"path";var Z=/^(?:\/[A-Za-z0-9._~-]+)+$/;function F(r){if(!/^[\x20-\x21\x23-\x7E]+$/.test(r.apiKey))throw new Error("apiKey contains invalid characters (quotes, newlines, or control chars)");if(r.deliveryPath&&!Z.test(r.deliveryPath))throw new Error("deliveryPath must be an absolute URL path (e.g. /api/corsair)");if(r.caCertPath&&/["\x00-\x1F\x7F]/.test(r.caCertPath))throw new Error("caCertPath contains invalid characters (quotes or control chars)");let o=[`serverAddr = "${r.serverAddr}"`,`serverPort = ${r.serverPort}`,"loginFailExit = true",`metadatas.token = "${r.apiKey}"`];if(r.deliveryPath&&o.push(`metadatas.path = "${r.deliveryPath}"`),r.caCertPath){let e=/^[A-Za-z]:[\\/]|^\\\\/.test(r.caCertPath)?r.caCertPath.replace(/\\/g,"/"):r.caCertPath.replace(/\\/g,"\\\\");o.push("transport.tls.enable = true",`transport.tls.serverName = "${r.serverName??r.serverAddr}"`,`transport.tls.trustedCaFile = "${e}"`)}return o.push("","[[proxies]]",`name = "corsair-${r.slug}"`,'type = "http"','localIP = "127.0.0.1"',`localPort = ${r.localPort}`,`subdomain = "${r.slug}"`,""),o.join(`
|
|
2
|
+
`)}import K from"http";var Q=3e4,J=new Set(["host","forwarded","x-real-ip"]);function V(r){return J.has(r)||r.startsWith("x-forwarded-")}function M(r,o=w){let n=K.createServer((e,t)=>{let d=e.url??"/",i;try{i=new URL(d,"http://127.0.0.1")}catch{t.statusCode=400,t.end("Bad request");return}if(/%2f|%5c/i.test(i.pathname)){t.statusCode=400,t.end("Bad request");return}if(!(i.pathname===o||i.pathname.startsWith(`${o}/`))){t.statusCode=404,t.end("Not found");return}let E={host:`127.0.0.1:${r}`};for(let[c,u]of Object.entries(e.headers))u!==void 0&&!V(c)&&(E[c]=u);let a=K.request({host:"127.0.0.1",port:r,method:e.method,path:i.pathname+i.search,headers:E,timeout:Q},c=>{let u={};for(let[y,p]of Object.entries(c.headers))p!==void 0&&y!=="set-cookie"&&(u[y]=p);t.writeHead(c.statusCode??502,u),c.pipe(t)});a.on("timeout",()=>a.destroy()),a.on("error",()=>{if(!t.writableEnded){if(t.headersSent){t.destroy();return}t.statusCode=502,t.end("Bad gateway")}}),e.on("error",()=>a.destroy()),t.on("close",()=>{a.destroyed||a.destroy()}),e.pipe(a)});return new Promise((e,t)=>{n.once("error",t),n.listen(0,"127.0.0.1",()=>{let d=n.address(),i=typeof d=="object"&&d?d.port:0;e({port:i,close:()=>new Promise(P=>{n.close(()=>P())})})})})}var z=15e3,nr=/start proxy success/i,D=/start error/i,j=/^[a-z0-9.-]+$/i;async function or(r){let o=r.apiUrl.replace(/\/$/,""),n=await fetch(`${o}/api/dev/tunnel-config`,{headers:{authorization:`Bearer ${r.apiKey}`},signal:AbortSignal.timeout(z)});if(!n.ok)throw new Error(`Hub tunnel-config failed (HTTP ${n.status})`);let e=await n.json();if(!e.slug||!/^[a-z0-9-]+$/.test(e.slug))throw new Error("Hub tunnel-config returned an invalid slug");if(!e.serverAddr||!j.test(e.serverAddr))throw new Error("Hub tunnel-config returned an invalid server address");if(!Number.isInteger(e.serverPort)||e.serverPort<1||e.serverPort>65535)throw new Error("Hub tunnel-config returned an invalid server port");if(e.serverName!==void 0&&!j.test(e.serverName))throw new Error("Hub tunnel-config returned an invalid serverName");let t=e.caCert??null;if(t&&!t.startsWith("-----BEGIN CERTIFICATE-----"))throw new Error('Hub tunnel-config returned a caCert that does not begin with "-----BEGIN CERTIFICATE-----"');return{serverAddr:e.serverAddr,serverPort:e.serverPort,slug:e.slug,caCert:t,serverName:e.serverName}}async function Tr(r){let{port:o,apiUrl:n,apiKey:e,shareHost:t=L,timeoutMs:d=2e4,onClose:i}=r,{serverAddr:P,serverPort:E,slug:a,caCert:c,serverName:u}=await or({apiUrl:n,apiKey:e}),y=O(),p=sr(),T=await M(o,p),b,$;try{b=rr(S(tr(),"corsair-frpc-")),$=S(b,"frpc.toml");let f=c?S(b,"ca.crt"):void 0;f&&c&&G(f,c,{mode:384}),G($,F({serverAddr:P,serverPort:E,apiKey:e,slug:a,localPort:T.port,caCertPath:f,serverName:u,deliveryPath:p}),{mode:384})}catch(f){throw await T.close(),f}let W=`https://${a}.${t}`;return new Promise((f,q)=>{let h=!1,N=!1,g="",l=X(y,["-c",$],{stdio:["ignore","pipe","pipe"]}),A=()=>{T.close(),er(b,{recursive:!0,force:!0})},_=!1,H=()=>{l.killed||l.kill(),A()};process.once("exit",H);let R=()=>{_||(_=!0,process.removeListener("exit",H),process.removeListener("SIGINT",C),process.removeListener("SIGTERM",C),l.stdout.removeAllListeners("data"),l.stderr.removeAllListeners("data"),l.killed||l.kill(),A())},C=s=>{R(),process.kill(process.pid,s)};process.once("SIGINT",C),process.once("SIGTERM",C);let v=s=>{h||(h=!0,clearTimeout(U),R(),q(s))},x=async s=>{if(!N){if(g+=s.toString(),D.test(g)){v(new Error(`frpc rejected the tunnel: ${ir(g)}`));return}if(nr.test(g)){N=!0,clearTimeout(U);try{await cr({apiUrl:n,apiKey:e})}catch(m){v(m instanceof Error?m:new Error(String(m)));return}h||(h=!0,f({url:W,stop:R}))}}};l.stdout.on("data",s=>{x(s)}),l.stderr.on("data",s=>{x(s)}),l.on("error",s=>{v(new Error(`Failed to spawn frpc: ${s.message}`))}),l.on("exit",s=>{if(!h){let m=ar(g),Y=m?` \u2014 ${m}`:"";v(new Error(`frpc exited early (code ${s??"null"}) before the tunnel came up${Y}`));return}process.removeListener("exit",H),A(),i?.()});let U=setTimeout(()=>{v(new Error(`Timed out after ${d}ms waiting for frpc to establish the tunnel`))},d)})}function sr(){try{let r=new URL(I()).pathname.replace(/\/$/,"");return r&&r!=="/"?r:w}catch{return w}}function ir(r){return(r.split(`
|
|
3
|
+
`).find(n=>D.test(n))??"start error").trim()}function ar(r){return r.split(`
|
|
4
|
+
`).filter(n=>n.trim()!=="").at(-1)?.trim()??""}async function cr(r){let o=r.apiUrl.replace(/\/$/,""),n=await fetch(`${o}/api/dev/register`,{method:"POST",headers:{authorization:`Bearer ${r.apiKey}`},signal:AbortSignal.timeout(z)});if(!n.ok)throw new Error(`Hub tunnel-live ping failed (HTTP ${n.status})`)}export{or as fetchTunnelConfig,cr as pingTunnelLive,Tr as runTunnel};
|
package/dist/hub.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$a as $,Aa as Q,Ba as R,Ca as S,Da as T,Ea as U,Q as A,Ra as V,Sa as W,Xa as X,Ya as Y,Za as Z,_a as _,ab as aa,b as a,c as b,cb as ba,d as c,db as ca,e as d,eb as da,f as e,fa as B,fb as ea,g as f,gb as fa,h as g,ha as C,hb as ga,i,ia as D,ib as ha,j,jb as ia,k,kb as ja,l,lb as ka,m,mb as la,n,nb as ma,o,oa as E,ob as na,p,pa as F,pb as oa,q,qa as G,qb as pa,r,ra as H,rb as qa,s,sa as I,sb as ra,t,ta as J,tb as sa,u,ua as K,v,va as L,w,wa as M,x,xa as N,y,ya as O,z,za as P}from"./chunk-
|
|
1
|
+
import{$a as $,Aa as Q,Ba as R,Ca as S,Da as T,Ea as U,Q as A,Ra as V,Sa as W,Xa as X,Ya as Y,Za as Z,_a as _,ab as aa,b as a,c as b,cb as ba,d as c,db as ca,e as d,eb as da,f as e,fa as B,fb as ea,g as f,gb as fa,h as g,ha as C,hb as ga,i,ia as D,ib as ha,j,jb as ia,k,kb as ja,l,lb as ka,m,mb as la,n,nb as ma,o,oa as E,ob as na,p,pa as F,pb as oa,q,qa as G,qb as pa,r,ra as H,rb as qa,s,sa as I,sb as ra,t,ta as J,tb as sa,u,ua as K,v,va as L,w,wa as M,x,xa as N,y,ya as O,z,za as P}from"./chunk-H66F2BLQ.js";import{a as h,b as ta,c as ua,d as va,e as wa,f as xa}from"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{m as BROWSER_DELIVERY_TTL_MS,ua as CORSAIR_TUNNEL_PATH,ta as CORSAIR_TUNNEL_ZONE,u as DEFAULT_HUB_API_URL,va as FRPC_VERSION,v as HubNotConfiguredError,T as ManagedOAuthDeliveryError,n as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ca as attachManagedRefreshAuth,p as buildBrowserDeliveryRedirectUrl,s as buildClientBridgeBrowserDeliveryUrl,ea as createConnectSessionJti,ja as createConnectTokenJti,B as createHubConnectSession,C as createHubPermissionSession,da as createHubRouteHandlers,pa as createPermissionSessionJti,o as createSignedTokenJti,ia as decodeConnectSessionTokenFromPath,oa as decodeConnectTokenFromPath,sa as decodePermissionTokenFromPath,O as deliverConnectCreateLink,S as deliverSignedEnvelope,Q as describeDeliveryNetworkError,na as encodeConnectTokenForPath,M as extractConnectLinkFromDeliveryAck,F as extractProbeFromDeliveryAck,E as extractRunFromDeliveryAck,L as extractSyncFromDeliveryAck,D as formatHubApprovalMessage,a as formatProviderDisplayName,R as formatServerDeliveryError,wa as frpcPlatformKey,fa as getConnectSessionExpiryMs,V as getConnectStatusForTenant,ka as getConnectTokenExpiryMs,x as getHubConfig,ba as getManagedAccessToken,X as handleHubDeliveryGet,Y as handleHubDeliveryPost,_ as handleHubDeliveryRequest,Z as hubDeliveryToResponse,z as inferHubEnvironmentSlug,i as isLoopbackUrl,K as isServerDeliveryAckSuccessful,W as listHubProjectConnections,w as normalizeHubConfig,N as parseConnectLinkFromDeliveryBody,b as parseConnectSessionResponse,f as parseConnectStatusResponse,g as parseHubApiErrorBody,e as parseOAuthRefreshResponse,d as parsePermissionSessionResponse,c as parseProjectConnectionsResponse,J as parseServerDeliveryAckBody,P as parseSyncFromDeliveryBody,t as prepareClientBridgeDeliveryTransport,U as processManagedOAuthDelivery,A as registerHubWebhookTenantLink,j as resolveDeliveryTransport,xa as resolveFrpcBinary,h as resolveHubDeliveryUrl,y as resolveHubOAuthCallbackUrl,$ as respondToHubDelivery,aa as respondToHubDeliveryFromRequest,q as signBrowserDeliveryToken,ga as signConnectSessionToken,la as signConnectToken,G as signDeliveryEnvelope,qa as signPermissionToken,k as usesBrowserDelivery,l as validateProductionDeliveryUrl,r as verifyBrowserDeliveryToken,ha as verifyConnectSessionToken,ma as verifyConnectToken,H as verifyDeliveryEnvelope,ra as verifyPermissionToken,I as verifySignedTunnelDelivery};
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as te,b as ie}from"./chunk-RQ5QHONV.js";import{Ab as B,Bb as j,Cb as Y,Db as q,Eb as U,Fa as O,Fb as J,Gb as K,Lb as l,M as k,Mb as c,Na as A,Nb as d,Ob as m,R as x,S as P,T as S,Ta as L,Tb as X,U as b,Ua as F,Ub as z,Va as E,Vb as G,Wa as H,Wb as Q,Xb as V,Yb as Z,Zb as ee,bb as _,bc as ne,cc as re,dc as g,ec as oe,ga as w,ja as I,ka as T,la as R,ub as v,vb as W,wb as M,xb as N,yb as D,zb as $}from"./chunk-
|
|
1
|
+
import{a as te,b as ie}from"./chunk-RQ5QHONV.js";import{Ab as B,Bb as j,Cb as Y,Db as q,Eb as U,Fa as O,Fb as J,Gb as K,Lb as l,M as k,Mb as c,Na as A,Nb as d,Ob as m,R as x,S as P,T as S,Ta as L,Tb as X,U as b,Ua as F,Ub as z,Va as E,Vb as G,Wa as H,Wb as Q,Xb as V,Yb as Z,Zb as ee,bb as _,bc as ne,cc as re,dc as g,ec as oe,ga as w,ja as I,ka as T,la as R,ub as v,vb as W,wb as M,xb as N,yb as D,zb as $}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";function s(n){let o=n[g];if(!o)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return o.plugins}function se(n,o){let r=c(s(n),o);return typeof r=="string"?r:Array.isArray(r)?r.join(`
|
|
2
2
|
`):Object.values(r).flat().join(`
|
|
3
3
|
`)}function ae(n,o){return d(s(n),o)}function pe(n,o){return l(s(n),o)}var ue=Symbol.for("corsair:internal");function le(n,o){let r=n;for(let e of o){if(!r||typeof r!="object")return null;r=r[e]}return typeof r=="function"?r:null}function y(n){return n[ue]?.database}async function ce(n,o){let r=new Date().toISOString(),e=await n.permissions.find_by_token(o);if(!e)return console.error("executePermission: no permission found for token."),{error:"executePermission: no permission found for token."};if(e.status!=="approved")return console.error(`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`};if(e.expires_at<r){let t=y(n);return t&&await t.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",e.id).execute(),console.error(`executePermission: permission '${e.id}' has expired.`),{error:`executePermission: permission '${e.id}' has expired.`,endpoint:e.endpoint,plugin:e.plugin,result:null}}let h=e.tenant_id??"default",a=(n.withTenant?n.withTenant(h):n)[e.plugin];if(!a?.api)return console.error(`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`),{error:`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`,plugin:e.plugin,endpoint:e.endpoint,result:null};let p=le(a.api,e.endpoint.split("."));if(!p)return console.error(`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`};await n.permissions.set_executing(e.id);try{let t=typeof e.args=="string"?JSON.parse(e.args):e.args,i=await p(t);return await n.permissions.set_completed(e.id),{plugin:e.plugin,endpoint:e.endpoint,result:i}}catch(t){let i=t instanceof Error?t.message:String(t),u=y(n);return u&&await u.db.updateTable("corsair_permissions").set({status:"failed",error:i,updated_at:new Date}).where("id","=",e.id).execute(),{plugin:e.plugin,endpoint:e.endpoint,result:null,error:i}}}export{_ as AuthMissingError,te as CorsairClientError,F as DEFAULT_BODY_STALL_TIMEOUT_MS,L as DEFAULT_MAX_BODY_BYTES,I as PermissionRequiredError,T as ReadonlyForbiddenError,Z as asRecord,G as collectPluginWebhookMatchers,oe as createCorsair,ie as createCorsairClient,re as decodePubSubData,ce as executePermission,ne as firstString,m as formatDocSchemaShape,Q as getHeader,ae as getSchema,pe as getStructuredSchema,se as listOperations,v as managementHandler,X as matchWebhookPlugin,z as matchWebhookPluginAndTenant,A as processCorsair,O as processWebhook,ee as readBodyRecord,M as registerCorsairRawBodyParser,P as resolveAccountFromWebhookLink,H as resolveBodyStallTimeoutMs,w as resolveConnectLink,E as resolveMaxBodyBytes,b as resolveTenantFromWebhookLink,S as resolveTenantIdFromWebhookLink,R as runReadonly,x as setWebhookTenantLink,k as setupCorsair,q as toAstroHandler,W as toExpressHandler,V as toExternalId,N as toFastifyHandler,D as toHonoHandler,$ as toNextJsHandler,B as toNodeHandler,J as toNuxtHandler,Y as toRemixHandler,j as toSvelteKitHandler,U as toTanStackHandler,K as toWebHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Oa as a,Pa as b,Qa as c}from"./chunk-
|
|
1
|
+
import{Oa as a,Pa as b,Qa as c}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{a as deriveAck,b as pollOnce,c as startConnectLoop};
|
package/dist/oauth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{O as a,P as b,V as c,W as d,X as e,Y as f,Z as g,_ as h}from"./chunk-
|
|
1
|
+
import{O as a,P as b,V as c,W as d,X as e,Y as f,Z as g,_ as h}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{d as OAuthCallbackError,c as buildOAuthAuthorizeUrl,b as decodeOAuthState,a as encodeOAuthState,e as generateOAuthUrl,f as processOAuthCallback,g as renewSubscriptions,h as startSubscriptionRenewal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as a,N as b}from"./chunk-
|
|
1
|
+
import{M as a,N as b}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as a,aa as b,ba as c,ca as d}from"./chunk-
|
|
1
|
+
import{$ as a,aa as b,ba as c,ca as d}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as buildConnectPluginManifest,a as buildConnectPluginManifestFromContext,d as ensureConnectAccountRows,c as ensureConnectAccountRowsFromContext};
|
package/dist/setup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as a,N as b}from"./chunk-
|
|
1
|
+
import{M as a,N as b}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
package/dist/tunnel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ga as f,Ha as g,Ia as h,Ja as i,Ka as j,La as k,Ma as l,Na as m,R as b,S as c,T as d,U as e,r as a}from"./chunk-
|
|
1
|
+
import{Ga as f,Ha as g,Ia as h,Ja as i,Ka as j,La as k,Ma as l,Na as m,R as b,S as c,T as d,U as e,r as a}from"./chunk-H66F2BLQ.js";import"./chunk-3TC2WIUS.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{l as applyPermissionDecision,f as executeWorkflowRun,h as isAuthCredentialsBrowserDelivery,k as isByoOAuthBrowserDelivery,j as isManagedBrowserDelivery,i as isPermissionBrowserDelivery,m as processCorsair,c as resolveAccountFromWebhookLink,e as resolveTenantFromWebhookLink,d as resolveTenantIdFromWebhookLink,g as runReadonlyProbe,b as setWebhookTenantLink,a as verifyBrowserDeliveryToken};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsair",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.122",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -85,10 +85,10 @@
|
|
|
85
85
|
"optionalDependencies": {
|
|
86
86
|
"@corsair-dev/frpc-darwin-arm64": "0.1.117",
|
|
87
87
|
"@corsair-dev/frpc-linux-arm64": "0.1.117",
|
|
88
|
-
"@corsair-dev/frpc-win32-x64": "0.1.117",
|
|
89
|
-
"@corsair-dev/frpc-win32-arm64": "0.1.117",
|
|
90
88
|
"@corsair-dev/frpc-linux-x64": "0.1.117",
|
|
91
|
-
"@corsair-dev/frpc-darwin-x64": "0.1.117"
|
|
89
|
+
"@corsair-dev/frpc-darwin-x64": "0.1.117",
|
|
90
|
+
"@corsair-dev/frpc-win32-arm64": "0.1.117",
|
|
91
|
+
"@corsair-dev/frpc-win32-x64": "0.1.117"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@testing-library/react": "^16.3.2",
|