corsair 0.1.108 → 0.1.110
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/{browser-delivery-ClbNhluI.d.ts → browser-delivery-DSOMrzVq.d.ts} +1 -1
- package/dist/chunk-AIDBRYAC.js +66 -0
- package/dist/client/react/index.d.ts +3 -3
- package/dist/{connect-JSSSZTJ4.js → connect-GMIO7HOY.js} +1 -1
- package/dist/core.d.ts +6 -6
- package/dist/core.js +1 -1
- package/dist/hub.d.ts +20 -8
- package/dist/hub.js +1 -1
- package/dist/{index-F_9QUwf4.d.ts → index-BfatdOwQ.d.ts} +88 -4
- package/dist/{index-CCwyDzOb.d.ts → index-DU9NOasm.d.ts} +152 -3
- package/dist/{index-BzMy2KpY.d.ts → index-Down-zOl.d.ts} +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +1 -1
- package/dist/oauth.d.ts +2 -2
- package/dist/oauth.js +1 -1
- package/dist/{setup-U5CPTDCM.js → setup-GLFWEPTA.js} +1 -1
- package/dist/{setup-introspect-YSOQWBTI.js → setup-introspect-LMUCDRCJ.js} +1 -1
- package/dist/setup.d.ts +3 -3
- package/dist/setup.js +1 -1
- package/dist/{tenant-match-utils-DhiFkgcG.d.ts → tenant-match-utils-BIM8e0pe.d.ts} +2 -2
- package/dist/tunnel.d.ts +54 -6
- package/dist/tunnel.js +1 -1
- package/dist/{types-MvrzaDrs.d.ts → types-Ce3Ii8Xs.d.ts} +1 -1
- package/dist/{types-Bsv_KdHs.d.ts → types-DfIEIfeF.d.ts} +5 -2
- package/package.json +1 -1
- package/dist/chunk-F5GBHMO2.js +0 -38
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import{a as ro,b as fe,c as oo,d as w,e as U,f as io,g as N,h as F,i as R,j as vn,k as so,l as ao,m as At,n as uo,o as co}from"./chunk-WDF3YE27.js";import{a as to}from"./chunk-IGGCNGU2.js";import{ZodBoolean as Yu,ZodDate as Qu,ZodEnum as Xu,ZodNullable as ec,ZodNumber as nc,ZodObject as tc,ZodOptional as rc,ZodRecord as oc,ZodString as ic,ZodType as sc}from"zod";var Pn=["activetrail","agentql","ahrefs","airtable","algolia","amplitude","asana","bitwarden","bluesky","box","cal","calendly","canva","cloudflare","confluence","cursor","datadog","deepseek","digitalocean","discord","dodopayments","dropbox","exa","figma","firecrawl","fireflies","gemini","github","gitlab","gmail","googlebigquery","googlecalendar","googledocs","googledrive","googlemeet","googlesheets","grafana","hackernews","hashnode","heygen","hubspot","insightoai","instagram","intercom","jira","linear","linkedin","mailchimp","monday","neon","notion","ollama","onedrive","onepassword","openai","openweathermap","oura","outlook","pagerduty","perplexityai","posthog","razorpay","reddit","resend","retailed","sentry","sharepoint","slack","spotify","strava","stripe","supabase","tally","tavily","teams","telegram","todoist","trello","twilio","twitter","twitterapiio","typeform","vapi","whatsapp","vercel","xquik","youtube","zendesk","zohomail","zoom"],lo={activetrail:"Active Trail",agentql:"AgentQL",ahrefs:"Ahrefs",airtable:"Airtable",algolia:"Algolia",amplitude:"Amplitude",asana:"Asana",bitwarden:"Bitwarden",bluesky:"Bluesky",box:"Box",cal:"Cal",calendly:"Calendly",canva:"Canva",cloudflare:"Cloudflare",confluence:"Confluence",cursor:"Cursor",datadog:"Datadog",deepseek:"DeepSeek",digitalocean:"DigitalOcean",discord:"Discord",dodopayments:"Dodo Payments",dropbox:"Dropbox",exa:"Exa",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googledocs:"Google Docs",googledrive:"Google Drive",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",hackernews:"Hacker News",hashnode:"Hashnode",heygen:"HeyGen",hubspot:"HubSpot",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jira:"Jira",linear:"Linear",linkedin:"LinkedIn",mailchimp:"Mailchimp",monday:"Monday",neon:"Neon",notion:"Notion",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",perplexityai:"Perplexity AI",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",retailed:"Retailed",sentry:"Sentry",sharepoint:"SharePoint",slack:"Slack",spotify:"Spotify",strava:"Strava",stripe:"Stripe",supabase:"Supabase",tally:"Tally",tavily:"Tavily",teams:"Teams",telegram:"Telegram",todoist:"Todoist",trello:"Trello",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",typeform:"Typeform",vapi:"Vapi",whatsapp:"WhatsApp",vercel:"Vercel",xquik:"XQuik",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom"};function ye(e){let n=lo[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}import{randomUUID as Ps}from"crypto";var ks="corsair:client-bridge";function xt(e){return new URL(e).origin}function Fe(e){let n=JSON.stringify({type:ks,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(xt(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
|
+
(function () {
|
|
3
|
+
var message = ${n};
|
|
4
|
+
var targetOrigin = ${t};
|
|
5
|
+
if (window.parent && window.parent !== window) {
|
|
6
|
+
window.parent.postMessage(message, targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
})();
|
|
9
|
+
</script></body></html>`}var bs=new Set(["localhost","127.0.0.1","[::1]","::1"]);function Rt(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:bs.has(n)}catch{return!1}}function tn(e){return e==="development"?"browser":"server"}function po(e){return tn(e)==="browser"}function go(e){return Rt(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as vs}from"crypto";var me=60*1e3,Re=300*1e3;import{createHmac as ws,randomBytes as Cs,timingSafeEqual as Ts}from"crypto";function ie(){return Cs(16).toString("base64url")}function rn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return ws("sha256",t).update(e).digest("base64url")}function ee(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=rn(o,t);try{if(!Ts(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 An(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=rn(i,n);return`${i}.${s}`}function on(e,n,t){let r=Math.floor(Date.now()/1e3);return An(e,n,r+Math.floor(t/1e3))}function Ie(e){return decodeURIComponent(e)}function It(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function fo(e){let n=e.trim();return n.length>0?n:null}function Ue(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Be(e,n){if(!fo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??vs(16).toString("base64url"),iat:t,exp:t+Math.floor(me/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=rn(o,n);return`${o}.${i}`}function he(e,n){return fo(n)?ee(e,n):null}function As(e){let n=xt(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 St(e){let n=Be(As(e),e.signingSecret);return Ue(e.deliveryUrl,n)}function yo(e){if(tn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ps(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:St(r)}}var sn="https://auth.corsair.dev";var se=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}};function xn(e){let n=(e.apiUrl?.trim()||sn).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}}function xs(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function H(e){let n=w(e).hub;if(!n||!xs(n))throw new se;return n}function mo(e){return e.replace(/\/$/,"")}function Rn(e){return e.oauthCallbackUrl?mo(e.oauthCallbackUrl.trim()):`${mo(e.apiUrl)}/oauth/callback`}function Le(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)")}function A(e){return typeof e=="string"&&e.length>0}function Rs(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Is(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function In(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!A(n.connectUrl)||!A(n.token)||!A(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:A(n.environmentId)?n.environmentId:n.projectId};return A(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Sn(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!A(r.tenantId)||!A(r.plugin)||!Rs(r.status)||!Is(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:A(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function _n(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!A(n.approvalUrl)||!A(n.token)||!A(n.projectId)||!A(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function En(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(A(n.access_token))return{access_token:n.access_token,refresh_token:A(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:A(n.scope)?n.scope:void 0};throw new Error(A(n.error)?A(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Ss(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function _s(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;A(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function Es(e,n,t,r){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"?e:n?"ready":t.some(i=>i.level==="integration"&&i.required&&!i.configured)?"missing_integration":t.some(i=>i.level==="account"&&i.required&&i.configured)?"partial":(r.length>0,"not_started")}function ho(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!A(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!A(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=_s(o.fields),a=Ss(o.missingRequiredFields),u=Es(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:A(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function Dn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}var Ds="3000",Os="/api/corsair";function Ms(e){return e.replace(/\/$/,"")}function ke(e){let n=e?.deliveryUrl?.trim()||process.env.CORSAIR_DELIVERY_URL?.trim();if(n){let r=/^https?:\/\//i.test(n)?n:`https://${n}`;return Ms(r)}return`http://localhost:${process.env.PORT?.trim()||Ds}${Os}`}function ko(e){return e.replace(/\/$/,"")}function _t(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return ke()}catch{return null}}function bo(e){let n=_t(e);return n?{"x-corsair-delivery-url":n}:{}}async function wo(e){let n=e.headers.get("content-type")??"",t=await e.text();if(!t)return null;if(!n.includes("application/json")&&t.trimStart().startsWith("<"))throw new Error(`Hub API returned HTML instead of JSON (HTTP ${e.status}). Check HUB_API_URL and deploy the latest hub API.`);try{return JSON.parse(t)}catch{throw new Error(`Hub API returned invalid JSON (HTTP ${e.status})`)}}function Co(e,n,t){if(n===404&&t)return t;let r=Dn(e);return r||`Hub API returned HTTP ${n}`}async function _(e){let n=ko(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...bo(e.hub)},body:JSON.stringify(e.body)}),r=await wo(t);if(!t.ok)throw new Error(Co(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=ko(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...bo(e.hub)}}),r=await wo(t);if(!t.ok)throw new Error(Co(r,t.status,e.notFoundMessage));return e.parseResponse(r)}import{createCipheriv as To,createDecipheriv as vo,randomBytes as On,scrypt as Hs}from"crypto";import{promisify as Fs}from"util";var Po=Fs(Hs),Mn="aes-256-gcm",Ao=12,Hn=16,Us=16,an=32;function ae(){return On(an).toString("base64")}async function ue(e,n){let t=On(Us),r=await Po(n,t,an),o=On(Ao),i=To(Mn,r,o,{authTagLength:Hn}),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 Z(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 Po(n,s,an),p=vo(Mn,c,a,{authTagLength:Hn});return p.setAuthTag(u),Buffer.concat([p.update(l),p.final()]).toString("utf8")}function Et(e,n){let t=Buffer.from(n,"base64"),r=On(Ao),o=To(Mn,t,r,{authTagLength:Hn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function un(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=vo(Mn,i,s,{authTagLength:Hn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function be(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Et(o,n);return t}function ce(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=un(o,n);return t}function cn(e,n,t){let r=ce(e,n);return be(r,t)}function xo(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 Dt=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function O(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...F[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let m=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!m)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:m.id,config:Dt(m.config),dek:m.dek??null},a},updateIntegration:async m=>{let h=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...m.config!==void 0?{config:m.config}:{},...m.dek!==void 0?{dek:m.dek}:{},updated_at:new Date}).where("id","=",h.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let m=await u.getIntegration();if(!m.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Z(m.dek,r),l},p=async()=>{let m=await u.getIntegration(),h=await c(),b=m.config;return!b||Object.keys(b).length===0?{}:ce(b,h)},d=Promise.resolve(),g=m=>{let h=d.then(()=>f(m));return d=h.catch(()=>{}),h},f=async m=>{let h=await c(),b;try{b=await p()}catch(x){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,x),b={}}let C={...b};for(let[x,E]of Object.entries(m))E===null?delete C[x]:C[x]=E;let S=be(C,h);await u.updateIntegration({config:S})};return{get_dek:c,issue_new_dek:async()=>{let m=await u.getIntegration(),h=ae(),b={};if(m.dek){let S=await Z(m.dek,r),x=m.config;x&&Object.keys(x).length>0&&(b=cn(x,S,h))}let C=await ue(h,r);return await u.updateIntegration({config:b,dek:C}),l=h,h},...xo(p,g,s)}}function D(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...F[n].account,...s],l=null,c=null,p=async()=>{if(c)return c;let k=!1;for(;;){let T=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!T){if(!k&&a){k=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:T.id,config:Dt(T.config),dek:T.dek??null},c}},d={kek:o,integrationName:t,tenantId:r,getIntegration:p,getAccount:async()=>{if(l)return l;let k=!1;for(;;){let T=await p(),v=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",T.id).executeTakeFirst();if(!v){if(!k&&a){k=!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:v.id,config:Dt(v.config),dek:v.dek??null},l}},updateAccount:async k=>{let T=await d.getAccount();await i.db.updateTable("corsair_accounts").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",T.id).execute(),l=null}},g=null,f=null,y=async()=>{if(g)return g;let k=await d.getAccount();if(!k.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Z(k.dek,o),g},m=async()=>{if(f)return f;let k=await d.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Z(k.dek,o),f},h=async()=>{let k=await d.getAccount(),T=await y(),v=k.config;return!v||Object.keys(v).length===0?{}:ce(v,T)},b=async()=>{let k=await d.getIntegration(),T=await m(),v=k.config;return!v||Object.keys(v).length===0?{}:ce(v,T)},C=Promise.resolve(),S=k=>{let T=C.then(()=>x(k));return C=T.catch(()=>{}),T},x=async k=>{let T=await y(),v;try{v=await h()}catch(P){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,P),v={}}let j={...v};for(let[P,Y]of Object.entries(k))Y===null?delete j[P]:j[P]=Y;let re=be(j,T);await d.updateAccount({config:re})},E={get_dek:y,issue_new_dek:async()=>{let k=await d.getAccount(),T=ae(),v={};if(k.dek){let re=await Z(k.dek,o),P=k.config;P&&Object.keys(P).length>0&&(v=cn(P,re,T))}let j=await ue(T,o);return await d.updateAccount({config:v,dek:j}),g=T,T},...xo(h,S,u)};return n==="oauth_2"&&(E.get_integration_credentials=async()=>{let k=await b();return{...k,client_id:k.client_id||null,client_secret:k.client_secret||null,redirect_url:k.redirect_url??null}}),E}async function Ro(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=ae(),i=await ue(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Io(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=ae(),a=await ue(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var Bs=new Set(["webhook_signature","expires_at","scope","redirect_url"]);function we(e){return Bs.has(e)}function Ls(e,n){return we(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Ns(e){return!we(e)}function $s(e){switch(e){case"oauth_2":case"managed":return["access_token","refresh_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ws(e,n){return $s(e).every(r=>n.find(i=>i.level==="account"&&i.name===r)?.configured??!1)}async function So(e,n){if(!e)return!1;let t=N(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function js(e,n){let r=e.authConfig?.[n]?.integration??[];return[...F[n].integration,...r]}function Ks(e,n){let r=e.authConfig?.[n]?.account??[];return[...F[n].account,...r]}function qs(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:Ws(n,t),fields:t,missingRequiredFields:r}}async function Se(e,n,t){let r=R(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=O({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=D({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=js(n,r),p=Ks(n,r),d=[];for(let g of c)d.push({name:g,level:"integration",required:Ls(r,g),configured:await So(u,g)});for(let g of p)d.push({name:g,level:"account",required:Ns(g),configured:await So(l,g)});return qs(n.id,r,d)}async function ln(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 Se(e,s,r);a&&i.push(a)}return i}function Fn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var _o=Symbol.for("corsair:internal"),Eo=new WeakMap,Do=new WeakMap;function Zs(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Gs(e){if(e.database){let t=Eo.get(e.database);return t||(t=new Map,Eo.set(e.database,t)),t}let n=Do.get(e);return n||(n=new Map,Do.set(e,n)),n}function Js(e){return e.multiTenancy?{withTenant:()=>({}),[_o]:e}:{[_o]:e}}async function Ne(e,n){if(!e.database)return;let t=n.trim()||"default",r=Gs(e),o=Zs(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-GLFWEPTA.js");await a(Js(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as dn from"crypto";function Ce(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function Ot(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 $e(e,n){let t=dn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var Mt=600*1e3;function Un(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=dn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!dn.timingSafeEqual(s,a)?null:Ot(r,{maxAgeMs:Mt})}function Oo(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function Mo(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 We(e,n){await _({hub:e,path:"/connections/report",body:Oo(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function zs(e,n){try{let t=H(e);_({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof se)return}}async function Vs(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!R(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Se(n,e.plugin,r);o&&Fo(e.hub,Mo({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Ho(e,n){zs(e,n)}function Fo(e,n){_({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function pn(e){Vs(e).catch(()=>{})}async function le(e,n){let t=w(e);if(!R(n.plugin))return;let o=await Se(t,n.plugin,n.tenantId);o&&Ho(e,Mo({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 Bn(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 Uo=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Ys(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 Qs(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 Z(n.dek,e.kek),r=Uo(n.config),o={};Object.keys(r).length>0&&(o=ce(r,t)),o[e.link.linkType]=e.link.externalId;let i=be(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function je(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await Ys({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=D({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),p=`set_${i.linkType}`,d=c[p];typeof d=="function"&&(await d(i.externalId),l=!0)}l||await Qs({database:n,kek:t,accountId:u,link:i})}async function Ht(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 Z(a.dek,t),c=Uo(a.config)[o];if(!c)continue;if(un(c,u)===i)return a}catch{continue}return null}async function Ln(e){return(await Ht(e))?.tenant_id??null}async function Bo(e){return Ln({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as Lo from"querystring";function _e(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}?${Lo.stringify(i)}`}async function No(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function Nn(e,n,t,r){if(!n.subscribe)return;let o=H(e),i=await No(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await le(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var B=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function $o(e){let n=e.oauthConfig;if(!n)throw new B("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Xs(e,n,t,r){let o=co(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=ae(),u=await ue(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function Ft(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=w(e,()=>new B("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=U(s,n,d=>new B("plugin_not_found",d)),u=$o(a),c=await O({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 d=new URL(_e({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return d.searchParams.delete("state"),{url:d.toString(),state:""}}let p=$e(Ce(n,r),s.kek);return{url:_e({oauthConfig:u,clientId:c,redirectUri:o,state:p}),state:p}}async function gn(e,n){let{code:t,state:r,redirectUri:o}=n,i=w(e,()=>new B("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new B("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let y=Un(r,i.kek);if(!y)throw new B("invalid_state","Invalid or tampered state parameter");s=y.plugin,a=y.tenantId}if(!i.database)throw new B("no_database","No database configured on corsair instance");let u=U(i,s,y=>new B("plugin_not_found",y)),l=$o(u),c=O({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),p=await c.get_client_id(),d=await c.get_client_secret();if(!p||!d)throw new B("credentials_not_configured",`Credentials not configured for '${s}'`);await Xs(i.database,s,a,i.kek);let g=await $n(t,p,d,l,o);if(!g.access_token)throw new B("no_access_token",`No access_token returned from ${l.providerName}`);let f=D({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 le(e,{plugin:u,tenantId:a}).catch(()=>{});try{let y=await Bn(i.plugins,s,g);if(y){try{let m=u.authConfig?.oauth_2?.account??[];await je({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:y,authType:"oauth_2",extraAccountFields:m})}catch(m){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,m)}i.hub&&We(i.hub,{plugin:s,tenantId:a,link:y,authType:"oauth_2"})}}catch(y){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,y)}if(u.subscribe)try{await Nn(e,u,a,f)}catch(y){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,y)}return{plugin:s,tenantId:a}}async function ea(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??Nn,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=D({authType:"oauth_2",integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]}),p=u.keyBuilder;if(p){let d=Object.create(c,{get_expires_at:{value:async()=>"0"}});await p({authType:"oauth_2",keys:d},"endpoint")}await o(n,u,a.tenantId,c),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 Wo(e){let n=w(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 ea({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function na(e,n={}){let t=!1,r=()=>{t||(t=!0,Wo(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 jo(e){if(!w(e).database)throw new Error("A database must be configured to provision Corsair integrations");await Wn(e,{silent:!0})}async function Ke(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ne(t,n)}var ta=Symbol.for("corsair:internal"),ra=new Set(["access_token","refresh_token","expires_at","scope"]);function oa(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function ia(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!we(t)&&!ra.has(t)):n.filter(t=>!we(t))}function Ko(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function sa(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function aa(e){return{[ta]:Ko(e)}}async function jn(e,n,t={}){let r=Rn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Ko(e),a=aa(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=R(u);if(!l)continue;let c=oa(l),p=t.providerNameOverrides?.[u.id]??ye(u.id),d=await Se(s,u,n),g=vn(u,l),f=ia(l,g),y={plugin:u.id,providerName:p,authKind:c,alreadyConfigured:d?.connected??!1};if(f.length>0&&(y.credentialFields=f),c==="oauth"){let h=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(y.oauthMode=h,!t.skipOAuthUrlGeneration&&h!=="managed")try{let b=await Ft(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});y.oauthUrl=b.url}catch(b){y.setupError=b instanceof Error?b.message:`Could not prepare OAuth for ${u.id}`}}o.push(y)}return o}async function Xl(e,n,t={}){let r=w(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return jn({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function qo(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ne(e.internalConfig??sa(e),n)}async function Zo(e,n){await Ke(e,n)}async function Go(e,n){let t=Le(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ke({deliveryUrl:n.deliveryUrl})),_({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:In})}async function Ut(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await qo(t,n.tenantId);let r=await jn(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 Go(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function Kn(e,n){let t=w(e),r=H(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Zo(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 jn(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 Go(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}function Jo(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function ua(e,n){return n&&!n.has(e.id)?!1:R(e)!==null}async function zo(e,n,t={}){let r=w(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await ln(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>ua(l,i)).map(l=>{let c=R(l),p=a.get(l.id);return p?{plugin:l.id,providerName:ye(l.id),authKind:Jo(c),status:p.status,connected:p.connected,fields:p.fields.map(d=>({name:d.name,level:d.level,required:d.required,configured:d.configured})),missingRequiredFields:p.missingRequiredFields}:{plugin:l.id,providerName:ye(l.id),authKind:Jo(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function Vo(e,n){let t=H(e);return $({hub:t,path:`/projects/${encodeURIComponent(n.projectId)}/connections`,notFoundMessage:"Hub REST API not found at /projects/:id/connections. Check HUB_API_URL and ensure the Hub API is deployed.",parseResponse:Sn})}function qe(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var G=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function ca(e){let n=e.oauthConfig;if(!n)throw new G("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Bt(e,n){let t=w(e,()=>new G("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new G("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new G("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=Un(n,t.kek);if(!o)throw new G("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=U(t,i,d=>new G("plugin_not_found",d)),u=ca(a),c=await O({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new G("client_id_not_configured",`client_id not configured for '${i}'`);let p=_e({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:p,state:n}}import{AsyncLocalStorage as da}from"async_hooks";import{randomBytes as pa}from"crypto";import{v4 as ga}from"uuid";async function qn(e,n){let t=Le(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=ke({deliveryUrl:n.deliveryUrl})),_({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:_n})}function Zn(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var Lt="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 $t(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Yo(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function Nt(e){return Zn(e)}async function Wt(e,n){if($t(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Yo(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await qn(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:la(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function la(e){try{return JSON.parse(e)}catch{return e}}async function Gn(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await Wt(e,n);return{...n,approvalUrl:r}}async function jt(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:p}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await Wt({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return $t(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):Nt(g):Lt:r?g?Nt(g):`Action '${p}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:Lt}var Ze=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Xo=new da,Jn=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 Kt(e){return Xo.run(!0,e)}function ei(){return Xo.getStore()===!0}function qt(e,n){if(ei()&&n!=="read")throw new Jn(e,n)}var fa={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 ya(e,n,t){return t!==void 0?t:fa[n][e]}function Zt(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 ni(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 Qo(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 ti(e){let n=ya(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
|
+
Action: ${r}`,`
|
|
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,y=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",y).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
|
+
Action: ${r}`,`
|
|
13
|
+
Permission ID: ${a.id}`,`
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Qo(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=ga(),l=pa(32).toString("hex"),c=e.timeoutMs??600*1e3,p=new Date(Date.now()+c).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:u,created_at:new Date,updated_at:new Date,token:l,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:p}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
15
|
+
Action: ${r}`,`
|
|
16
|
+
Permission ID: ${u}`,`
|
|
17
|
+
Permission token: ${l}`,`
|
|
18
|
+
Expires at: ${p}`,`
|
|
19
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Qo(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:p}}var I=class extends Error{status;code;extra;constructor(n,t,r,o={}){super(r??t),this.name="ManagementApiError",this.status=n,this.code=t,this.extra=o}};function M(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function ri(e){let n={error:e.code,message:e.message,...e.extra};return M(e.status,n)}function Te(e){return new I(404,"not_found",e)}function de(e,n={}){return new I(400,"bad_request",e,n)}function oi(e,n){return U(e,n,t=>Te(t))}async function ii(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=O({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=F[t].integration,i=r,s;try{s=await Promise.all(o.map(l=>i[`get_${l}`]()))}catch{s=o.map(()=>null)}let a=o.filter((l,c)=>s[c]==null),u;return t==="oauth_2"?u=!a.includes("client_id")&&!a.includes("client_secret"):u=a.length===0,{configured:u,missingFields:a}}async function si(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await ii(e,n);return{id:e.id,authType:t,configured:o,missingFields:i,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function zn(){return{ok:!0}}async function Ge(e){return Promise.all(e.plugins.map(n=>si(n,e)))}async function Vn(e,n){let t=oi(e,n);return si(t,e)}async function ma(e,n){return e.database?(await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.id as accountId","a.dek as dek","i.name as integrationName"]).where("a.tenant_id","=",n).execute()).map(r=>({integrationName:r.integrationName,hasCredentials:!!r.dek})):[]}async function ai(e,n){let t=await ma(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function Je(e){let n=new Map;if(n.set("default",{id:"default",accounts:[],connectedPlugins:[]}),e.database){let t=await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id","a.dek as dek","i.name as integrationName"]).execute();for(let r of t){let o=r.tenant_id;if(!o)continue;let i=n.get(o);i||(i={id:o,accounts:[],connectedPlugins:[]},n.set(o,i));let s=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function Yn(e,n){if(!n)throw de("Tenant id must be a non-empty string");return ai(e,n)}async function Qn(e,n){let t=n?.id?.trim();if(!t)throw de("Tenant id is required",{missingFields:["id"]});return ai(e,t)}async function Xn(e,n){let t=n?.trim()||"default",r={},o=await ln(e,t);for(let i of o)r[i.plugin]=Fn(i);for(let i of e.plugins)i.id in r||(!i.options?.authType||!e.database||!e.kek?r[i.id]="missing_credentials":r[i.id]="not_connected");return r}async function Gt(e,n){if(!e.database)throw Te(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Te(`Permission '${n}' not found`);return Gn(e,t)}function ha(e){if(!e.oauthConfig)throw de(`Plugin '${e.id}' has no oauthConfig`)}function ka(e){if(!e.manual)throw new I(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Jt(e){let n=ka(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new I(500,"connect_not_configured","Manual connect requires manual.baseUrl and manual.redirectUri. Use hub for hosted connect, or set both URLs for manual OAuth.");return n}function ba(e){let n=!!e.hub,t=qe(e.manual);if(!n&&!t)throw new I(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function ui(e){if(!e.database||!e.kek)throw new I(500,"database_not_configured","A database and kek are required to issue connect links.")}async function wa(e,n){let t=n?.plugin?.trim();if(!t)throw de("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=oi(e,t);ha(o);let i=Jt(e);ui(e);let s=await ii(o,e);if(!s.configured)throw new I(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=$e(Ce(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new I(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return u.searchParams.set("state",a),{connectUrl:u.toString(),expiresAt:new Date(Date.now()+Mt).toISOString()}}async function Ca(e,n,t){ui(n);let o={tenantId:t.tenantId?.trim()||"default",oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let s=t.providerName?.trim();s&&(o.providerName=s);let a=await Kn(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function et(e,n,t){return ba(n),n.hub?Ca(e,n,t):wa(n,t)}async function nt(e,n,t){if(n.hub&&!qe(n.manual))throw new I(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw de("state is required",{missingFields:["state"]});Jt(n);try{return await Bt(e,r)}catch(o){if(o instanceof G)switch(o.code){case"invalid_state":throw de("Invalid or expired state");case"client_id_not_configured":throw new I(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new I(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function tt(e,n,t){if(n.hub&&!qe(n.manual))throw new I(400,"hub_mode","oauthCallback is not used with hub config. Hub delivers tokens to your deliveryUrl.");let r=t?.code?.trim(),o=t?.state?.trim(),i=[];if(r||i.push("code"),o||i.push("state"),i.length)throw de("Missing required fields",{missingFields:i});let s=Jt(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw de("Invalid or expired state");case"credentials_not_configured":throw new I(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new I(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function zt(e,n){if(!e.database)throw Te("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Te("Permission not found");return Gn(e,t)}async function ci(e,n){return"id"in n?Gt(e,n.id):zt(e,n.token)}import{createCipheriv as Ia,createDecipheriv as Xd,randomBytes as gi,scryptSync as Sa}from"crypto";import{createHmac as Vt,randomUUID as Ta,timingSafeEqual as di}from"crypto";function Yt(e){return e.run??null}function Qt(e){return e.probe??null}function pi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function rt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Vt("sha256",e.signingSecret.trim()).update(n).digest("hex");return{body:n,headers:{"content-type":"application/json","x-corsair-signature":`sha256=${r}`,"x-corsair-timestamp":t,"x-corsair-project":e.projectId,"x-corsair-nonce":Ta()}}}function Xt(e){let n=e.signingSecret.trim();if(!n)return!1;let t=pi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Re)return!1;let i=Vt("sha256",n).update(e.body).digest("hex");try{return di(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function ze(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=pi(e.signatureHeader);if(!t)return{ok:!1,error:"Invalid tunnel signature"};let r=Number(e.timestampHeader);if(!Number.isFinite(r))return{ok:!1,error:"Invalid or missing tunnel timestamp"};if(Math.abs(Date.now()-r*1e3)>Re)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Vt("sha256",n).update(e.body).digest("hex");try{if(!di(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function Ve(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function ot(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function it(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function fn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function er(e){return fn(Ve(e))}async function nr(e){let n=await ut({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=Ve(n.body),r=ot({httpOk:n.ok,status:n.status,body:t}),o=fn(t);if(!r||!o)throw new Error(at({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function st(e){return it(Ve(e))}function va(e){let n=e;for(;n;){if(n instanceof Error){let t=n.code;if(typeof t=="string")return t;n=n.cause;continue}if(typeof n=="object"&&n!==null&&"code"in n){let t=n.code;if(typeof t=="string")return t}break}}function li(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Pa="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",Aa="Check the delivery URL configured for this environment.";function xa(e){return`${e.ack.error?`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`:`App rejected the signed delivery (HTTP ${e.status} from ${e.deliveryUrl})`}. ${Pa}`}function Ra(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${Aa}`}function yn(e,n){let t=va(n),r=n instanceof Error?n.message:"Delivery request failed",o;switch(t){case"ECONNREFUSED":o="connection refused \u2014 nothing accepted a TCP connection on that host and port";break;case"ENOTFOUND":o="host not found \u2014 DNS could not resolve the hostname";break;case"ETIMEDOUT":case"UND_ERR_CONNECT_TIMEOUT":o="connection timed out before the app responded";break;case"ECONNRESET":o="connection reset while talking to the app";break;case"CERT_HAS_EXPIRED":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":o=`TLS certificate error (${t})`;break;default:o=r==="fetch failed"&&t?`${r} (${t})`:r}return[`Could not reach ${e}`,o].join(". ")}function at(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:yn(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return xa(e);if(e.status===404)return Ra(e);if(e.ack.error)return`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`;if(e.status>=500){let t=e.body.trim();return t?`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl}): ${li(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${li(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function ut(e){let{body:n,headers:t}=rt(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:yn(e.deliveryUrl,r)}}}var _a="aes-256-gcm",Ea=12,Da=16,Oa=16,Ma=32;function Ha(e,n){return Sa(e.trim(),n,Ma)}function tr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=gi(Oa),o=Ha(t,r),i=gi(Ea),s=Ia(_a,o,i,{authTagLength:Da}),a=JSON.stringify(e),u=Buffer.concat([s.update(a,"utf8"),s.final()]),l=s.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),u.toString("base64")].join(":")}var Fa=["invalid corsair instance","a database must be configured to sync connections from the app","a database must be configured on the corsair instance","signing secret is required to encrypt sync manifest"];function rr(e){if(e instanceof ro)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!Fa.some(t=>n.includes(t))}function Ua(e){if(!e)return[];let n=R(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!we(r)):[]}async function mn(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await Wn(e,{silent:!0});let[r,o]=await Promise.all([Je(t),Ge(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=Ua(t.plugins.find(u=>u.id===s.id));return{id:s.id,authType:s.authType,configured:s.configured,missingFields:s.missingFields,...a.length>0?{integrationCredentialFields:a}:{}}}),syncedAt:new Date().toISOString()};return tr(i,n)}async function ct(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=w(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 Ba(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 Ba(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-LMUCDRCJ.js"),{postHubConnectSession:i}=await import("./connect-GMIO7HOY.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})}var ne=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function lt(e,n){let t=w(e,()=>new ne("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ne("no_database","Database not configured");let r=U(t,n.plugin,c=>new ne("plugin_not_found",c)),o=R(r);if(!o)throw new ne("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ne("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await Ke(e,n.tenantId);let i=new Set(vn(r,o)),a=r.authConfig?.[o]?.account??[],u=D({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[c,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new ne("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let d=N(u,`set_${c}`);if(!d)throw new ne("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await d(p.trim()),l+=1}if(l===0)throw new ne("invalid_credentials","Provide at least one credential field to save");return await le(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var te=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function or(e,n){let t=w(e,()=>new te("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new te("no_database","Database not configured");let r=U(t,n.plugin,c=>new te("plugin_not_found",c)),o=R(r);if(!o)throw new te("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await jo(e);let i=new Set(so(r,o)),a=r.authConfig?.[o]?.integration??[],u=O({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[c,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new te("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let d=N(u,`set_${c}`);if(!d)throw new te("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await d(p.trim()),l+=1}if(l===0)throw new te("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var dt=new Map;function La(e){for(let[n,t]of dt)t<=e&&dt.delete(n)}function pt(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};let r=Date.now();return La(r),dt.has(t)?{ok:!1,error:"Delivery request already consumed"}:(dt.set(t,r+n),{ok:!0})}var ve=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function Ye(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a}=n;if(!o.trim())throw new ve("no_access_token","Managed OAuth delivery missing access_token");let u=w(e,()=>new ve("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new ve("no_database","No database configured on corsair instance");let l=U(u,t,p=>new ve("plugin_not_found",p));await Ke(e,r);let c=D({authType:"managed",integrationName:t,tenantId:r,kek:u.kek,database:u.database});await c.set_access_token(o),i&&await c.set_refresh_token(i),s&&await c.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await c.set_scope(a),await le(e,{plugin:l,tenantId:r}).catch(()=>{});try{let p=await Bn(u.plugins,t,{access_token:o,refresh_token:i,scope:a});if(p){try{let d=l.authConfig?.managed?.account??[];await je({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:p,authType:"managed",extraAccountFields:d})}catch(d){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,d)}u.hub&&We(u.hub,{plugin:t,tenantId:r,link:p,authType:"managed"})}}catch(p){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,p)}return{plugin:t,tenantId:r}}function Na(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function fi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Na(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=fi(o,n,[...t,r]);if(i)return i}return null}function $a(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Wa(e){let n=e["x-goog-resource-uri"],t=e["x-goog-channel-id"];if(!n||!t)return null;let r={resourceId:e["x-goog-resource-id"]||"",resourceState:e["x-goog-resource-state"]||"",resourceUri:n,channelId:t,channelExpiration:e["x-goog-channel-expiration"]||""};return n.includes("/drive/")&&(r.kind="drive#change"),{message:{data:Buffer.from(JSON.stringify(r)).toString("base64"),messageId:e["x-goog-message-number"]||""}}}async function yi(e,n,t,r,o){let i=$a(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Wa(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,p=o?.plugin,d=p?[p]:Pn;for(let g of d){let f=c[g];if(!f||!f.webhooks||!p&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let y=fi(f.webhooks,u);if(!y)continue;let m=y.path.join("."),h={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{}};try{let b=await y.webhook.handler(h),C=!!Object.keys(b.returnToSender||{})?.length;return{plugin:g,action:m,body:s,response:C?{...b?.returnToSender,success:!0}:{success:!0},...b.responseHeaders&&{responseHeaders:b.responseHeaders}}}catch(b){return console.error(`Error executing webhook handler for ${g}.${m}:`,b),{plugin:g,action:m,body:s,response:{success:!1,error:b instanceof Error?b.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as ja}from"crypto";import*as Ee from"vm";var mi="__corsairFailedStep",Ka=3e4,ir=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function hi(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function ki(e,n){return`st_${ja("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function gt(e){if(e instanceof Error)return e.message;if(e!==null&&typeof e=="object"&&"message"in e){let n=e.message;if(typeof n=="string")return n}return String(e)}var bi=new Set(["constructor","prototype","__proto__"]);function pe(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Za(e,n):t==="object"?qa(e):e}function qa(e){return new Proxy(e,{get(n,t){if(!bi.has(t))return pe(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Za(e,n){return new Proxy(e,{apply:(t,r,o)=>Ga(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!bi.has(r))return pe(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Ga(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>pe(n,void 0),n=>{throw pe(n,void 0)}):pe(e,void 0)}function Ja(e){let n=Object.create(null),t=Ee.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ee.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ee.runInContext(`(function (hostRun, hostSleep) {
|
|
20
|
+
const step = function step(name, fn) { return hostRun(name, fn); };
|
|
21
|
+
step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
|
|
22
|
+
return step;
|
|
23
|
+
})`,t,{filename:"corsair:sandbox:step"})((d,g)=>e.step(d,g),(d,g)=>e.step.sleep(d,g)),u=Ee.runInContext(`(function (sink) {
|
|
24
|
+
const fwd = (level) => function () {
|
|
25
|
+
try { sink(level, Array.prototype.slice.call(arguments)); } catch (_e) {}
|
|
26
|
+
};
|
|
27
|
+
return { log: fwd('log'), info: fwd('info'), warn: fwd('warn'), error: fwd('error'), debug: fwd('debug') };
|
|
28
|
+
})`,t,{filename:"corsair:sandbox:console"})((d,g)=>{let f=console[d]??console.log;try{f(...g)}catch{}});n.__corsair=pe(e.corsair,void 0),n.__payload=o,n.__step=s,n.__console=u;let l=Ee.runInContext(`(function () {
|
|
29
|
+
'use strict';
|
|
30
|
+
const module = { exports: {} };
|
|
31
|
+
const require = function (id) {
|
|
32
|
+
throw new Error('Workflow code may not import modules (attempted to require "' + id + '")');
|
|
33
|
+
};
|
|
34
|
+
(function (exports, module, require, console) {
|
|
35
|
+
${e.code}
|
|
36
|
+
})(module.exports, module, require, __console);
|
|
37
|
+
const main = module.exports.main;
|
|
38
|
+
if (typeof main !== 'function') {
|
|
39
|
+
throw new Error('Workflow code must export a \`main\` function');
|
|
40
|
+
}
|
|
41
|
+
return main(__corsair, __payload, __step);
|
|
42
|
+
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let c,p=new Promise((d,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,p]).finally(()=>clearTimeout(c))}async function sr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=ki(s,u);if(Object.hasOwn(n,l))return pe(n[l].output,void 0);try{let c=await a();return t.push({stepId:l,name:s,seq:u,status:"completed",output:c}),c}catch(c){if(hi(c))throw c;let p=gt(c);t.push({stepId:l,name:s,seq:u,status:"failed",error:p});let d=new Error(p);throw d[mi]=s,d}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=ki(s,u);if(Object.hasOwn(n,l))return;t.push({stepId:l,name:s,seq:u,status:"completed",output:null});let c=Number.isFinite(a)?Math.max(0,a):0;throw o=new ir(Date.now()+c,s),o};try{await Ja({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Ka});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(hi(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=gt(s),u=s!==null&&typeof s=="object"?s[mi]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as ft from"vm";var wi=1e4;async function ar(e){let n=Object.create(null),t=ft.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=pe(e.corsair,void 0);let r=Va(e.timeoutMs),o=`(async () => {
|
|
43
|
+
const __result = await (async () => {
|
|
44
|
+
${e.code}
|
|
45
|
+
})();
|
|
46
|
+
return JSON.stringify(__result) ?? 'null';
|
|
47
|
+
})()`;try{let i=await Kt(()=>{let s=ft.runInContext(o,t,{filename:"corsair:probe",timeout:r});s.catch(()=>{});let a,u=new Promise((l,c)=>{a=setTimeout(()=>c(new Error(`Probe exceeded ${r}ms time limit`)),r)});return Promise.race([s,u]).finally(()=>clearTimeout(a))});return{status:"ok",value:za(i)}}catch(i){return{status:"error",error:gt(i)}}}function za(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function Va(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?wi:Math.min(e,wi)}function De(e){return e.deliveryMode==="auth.credentials"}function hn(e){return e.deliveryMode==="connections.sync"}function yt(e){return e.deliveryMode==="connect.create_link"}function kn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function bn(e){return e.deliveryMode==="oauth.tokens"}function mt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!De(e)&&!hn(e)&&!yt(e)&&!kn(e)&&!bn(e)}function Ya(e){return{status:"ok",connectLink:{connectUrl:e.connectUrl,expiresAt:e.expiresAt},webhookResponse:{status:200,body:{status:"ok",connectUrl:e.connectUrl,expiresAt:e.expiresAt}}}}async function Qa(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await mn(e,n)}}}}}catch(t){return{status:"failed",retryable:rr(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Xa(e,n){try{let t=await ct(e,n);return Ya(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function ur(e,n){if(e instanceof Headers)return e.get(n)??void 0;let t=e[n]??e[n.toLowerCase()];return Array.isArray(t)?t[0]:typeof t=="string"?t:void 0}async function eu(e,n,t){let r=typeof t.tenantId=="string"?t.tenantId:typeof t.query?.tenantId=="string"?t.query.tenantId:void 0;return r||(!n.database||!t.plugin||!t.linkType||!t.externalId?void 0:await Ln({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function nu(e,n,t){let r=await eu(e,n,t),o={...t.query??{},...r?{tenantId:r}:{}},i=await yi(e,t.headers,t.body,o,t.plugin?{plugin:t.plugin}:void 0);if(!i.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(i.response&&i.response.success===!1)return{status:"failed",retryable:!1,error:typeof i.response.error=="string"?i.response.error:"Webhook handler failed"};let s=i.response?.returnToSender,a=s&&typeof s=="object"&&typeof s.validationToken=="string"&&Object.keys(s).length===1?s.validationToken:s||(i.response?.data??i.response);return{status:"ok",webhookResponse:{status:i.response?.statusCode??200,body:a,headers:i.responseHeaders}}}async function tu(e,n){return await gn(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function ru(e,n){return await Ye(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope}),{status:"ok"}}async function lr(e,n,t){let r=await cr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function cr(e,n,t){let r=w(e),o=n.token?.trim();if(!o)return{status:"failed",retryable:!1,error:"Permission token is required"};if(!r.database)return{status:"failed",retryable:!1,error:"Database not configured"};let i=new Date().toISOString(),s=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",o).executeTakeFirst();return s?s.status!=="pending"?{status:"ok"}:s.expires_at<i?(await r.database.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",s.id).execute(),{status:"failed",retryable:!1,error:"Permission has expired"}):(await r.database.db.updateTable("corsair_permissions").set({status:t,updated_at:new Date}).where("id","=",s.id).execute(),{status:"ok"}):{status:"failed",retryable:!1,error:"Permission not found"}}async function ou(e,n){try{return await lt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function iu(e,n){try{return await or(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Ci(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function su(e,n){try{let t=Ci(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await sr({corsair:t,code:n.code,payload:n.trigger?.payload??null,memoizedSteps:n.memoizedSteps})}}}}catch(t){return{status:"failed",retryable:!0,error:t instanceof Error?t.message:"Workflow run failed"}}}async function au(e,n){try{let t=Ci(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await ar({corsair:t,code:n.code,timeoutMs:n.timeoutMs})}}}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Probe failed"}}}async function dr(e,n,t={}){let r=w(e),o=ur(n.headers,"x-corsair-signature"),i=ur(n.headers,"x-corsair-timestamp"),s=ur(n.headers,"x-corsair-nonce");if(t.signingSecret?.trim()){let u=ze({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!u.ok)return{status:"failed",retryable:!1,error:u.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let l=pt(`nonce:${s.trim()}`,Re);if(!l.ok)return{status:"failed",retryable:!1,error:l.error}}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let a;try{a=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(a.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(a.type){case"webhook":return nu(e,r,a.payload);case"oauth.callback":return tu(e,a.payload);case"oauth.tokens":return ru(e,a.payload);case"permission.approve":return cr(e,a.payload,"approved");case"permission.deny":return cr(e,a.payload,"denied");case"auth.credentials":return ou(e,a.payload);case"integration.credentials":return iu(e,a.payload);case"connect.create_link":return Xa(e,a.payload);case"connections.sync":{let u=t.signingSecret?.trim();return u?Qa(e,u):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?su(e,a.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?au(e,a.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};default:return{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${String(a.type)}`}}}var pr=new Map;function Ti(e){let n;try{n=H(e)}catch{return}let t=_t(n);t&&pr.get(n.projectApiKey)!==t&&(pr.set(n.projectApiKey,t),_({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{pr.delete(n.projectApiKey)}))}var uu=[".corsair.dev"];function cu(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function lu(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:cu(n)?!0:uu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function vi(e){return!e||!lu(e)?null:{"Access-Control-Allow-Origin":e,"Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"content-type, x-corsair-signature, x-corsair-timestamp, x-corsair-project, x-corsair-nonce, access-control-request-private-network","Access-Control-Allow-Private-Network":"true","Access-Control-Max-Age":"0",Vary:"Origin"}}function Pi(e,n){if(!n)return e;let t=new Headers(e.headers);for(let[r,o]of Object.entries(n))t.set(r,o);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function gr(e,n){let t=new URL(e);return n.error?(t.searchParams.set("error",n.error),t.toString()):n.connectedPlugin?(t.searchParams.set("connected",n.connectedPlugin),t.toString()):(n.status!==void 0&&t.searchParams.set("status",Buffer.from(JSON.stringify(n.status)).toString("base64url")),t.toString())}async function fr(e,n){let t=H(e),o=new URL(n).searchParams.get("d");if(!o)return{type:"json",status:200,body:{status:"ok",message:"Corsair tunnel endpoint is active",timestamp:new Date().toISOString()}};let i=he(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=pt(`browser:${i.jti}`,me);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(hn(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connections sync delivery requires hubOrigin and requestId for client bridge"}};let a=await mn(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(yt(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let u=await ct(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:u.connectUrl,expiresAt:u.expiresAt}})}}if(De(i))return i.hubSuccessUrl?i.credentials?(await lt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:gr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:gr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(kn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await lr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(bn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await Ye(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope})}else{if(!mt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await gn(e,{code:i.code,state:i.state,redirectUri:i.redirectUri,trusted:!0,plugin:i.plugin,tenantId:i.tenantId})}}catch(a){let u=a instanceof Error?a.message:"Hub delivery failed";return hn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:yt(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:De(i)&&i.hubSuccessUrl?{type:"redirect",url:gr(i.hubSuccessUrl,{error:u})}:De(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:{type:"json",status:400,body:{error:u}}}return{type:"redirect",url:i.hubSuccessUrl}}async function yr(e,n){let t=H(e),r=await dr(e,n,{signingSecret:t.signingSecret,allowWorkflowExecution:t.allowWorkflowExecution});if(r.status!=="ok")return{type:"json",status:r.retryable===!1?400:502,body:{error:r.error??"Tunnel processing failed"}};let o=r.webhookResponse;if(!o)return{type:"json",status:200,body:{status:"ok"}};let i=o.status??200,s=o.headers;return o.body&&typeof o.body=="object"&&!(o.body instanceof ArrayBuffer)?{type:"json",status:i,body:o.body,headers:s}:{type:"text",status:i,body:typeof o.body=="string"?o.body:o.body?JSON.stringify(o.body):null,headers:s}}function mr(e){if(e.type==="redirect")return Response.redirect(e.url,302);let n=new Headers;for(let[t,r]of Object.entries(e.headers??{}))typeof r=="string"&&n.set(t,r);return e.type==="json"?Response.json(e.body,{status:e.status,headers:n}):new Response(e.body,{status:e.status,headers:n})}async function hr(e,n){return n.method==="GET"?fr(e,n.url):yr(e,{headers:n.headers,body:n.body??""})}async function kr(e,n){try{let t=await hr(e,n);return mr(t)}catch(t){if(t instanceof se)return Response.json({error:t.message},{status:503});throw t}}async function Oe(e,n){Ti(e);let t=n.method.toUpperCase(),r=vi(n.headers.get("origin"));if(t==="OPTIONS")return r?new Response(null,{status:204,headers:r}):Response.json({error:"Method not allowed"},{status:405});if(t!=="GET"&&t!=="POST")return Response.json({error:"Method not allowed"},{status:405});let o=await kr(e,{method:t,url:n.url,headers:n.headers,body:t==="POST"?await n.text():void 0});return Pi(o,r)}var W=class extends Error{pluginId;authType;constructor(n,t,r){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t}};var Ai=300;async function br(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,[a,u,l]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!a&&!l)throw new W(o,"managed");let c=Math.floor(Date.now()/1e3);if(!s&&a&&u&&Number(u)>c+Ai)return{accessToken:a,expiresAt:Number(u),refreshed:!1};if(!l&&a&&!s){let g=u?Number(u):null;if(g===null||g>c+Ai)return{accessToken:a,expiresAt:g??c+3600,refreshed:!1}}let p=await pu(r,o,i),d=p.expires_in?c+p.expires_in:u?Number(u):c+3600;return await t.set_access_token(p.access_token),await t.set_expires_at(String(d)),p.refresh_token&&await t.set_refresh_token(p.refresh_token),p.scope&&await t.set_scope(p.scope),{accessToken:p.access_token,expiresAt:d,refreshed:!0}}function du(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function pu(e,n,t){try{return await _({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t},parseResponse:En})}catch(r){let o=r instanceof Error?r.message:"";throw du(o)?new W(n,"managed"):r}}async function xi(e,n){e._refreshAuth=async()=>(await br(n,{forceRefresh:!0})).accessToken}function Ri(e){return{delivery:n=>Oe(e,n),deliveryOptions:n=>Oe(e,n)}}var Ii=1200*1e3;function wr(){return ie()}function Cr(){return Ii}function Tr(e,n){return on(e,n,Ii)}function vr(e,n){return ee(e,n)}function Pr(e){return Ie(e)}var Si=600*1e3;function Ar(){return ie()}function xr(){return Si}function Rr(e,n){return on(e,n,Si)}function Ir(e,n){return ee(e,n)}function Sr(e){return It(e)}function _r(e){return Ie(e)}function Er(){return ie()}function Dr(e,n,t){return An(e,n,Math.floor(t.getTime()/1e3))}function Or(e,n){return ee(e,n)}function Mr(e){return Ie(e)}function _i(e){return e&&typeof e=="object"?e:{}}async function Hr(e,n){return _({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>t})}async function Fr(e,n){return _({hub:e,path:`/threads/${encodeURIComponent(n.threadId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Thread "${n.threadId}" not found`,parseResponse:t=>t})}async function Ur(e,n){return $({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=_i(t).threads;return Array.isArray(r)?r:[]}})}async function ht(e,n){return $({hub:e,path:`/threads/${encodeURIComponent(n.threadId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Thread "${n.threadId}" not found`,parseResponse:t=>{let r=_i(t).messages;return Array.isArray(r)?r:[]}})}function kt(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){let s=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
48
|
+
|
|
49
|
+
To generate a KEK, run: openssl rand -base64 ${an}`)}})}async function gu(e){let n=!1;for(;;){let t=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.integrationName).executeTakeFirst();if(!t){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Integration "${e.integrationName}" not found. Make sure to create the integration first.`)}let r=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",t.id).executeTakeFirst();if(!r){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Account not found for tenant "${e.tenantId}" and integration "${e.integrationName}". Make sure to create the account first.`)}return{integrationId:t.id,accountId:r.id,integration:{id:t.id,config:t.config,dek:t.dek??null},account:{id:r.id,config:r.config,dek:r.dek??null}}}}async function Ei(e){let{integrationId:n,accountId:t}=await gu(e);return{integrationId:n,accountId:t}}function Br(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function fu(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await Ut(t,{tenantId:n.tenantId,plugin:n.plugin,database:n.database,kek:n.kek,plugins:n.plugins,multiTenancy:n.multiTenancy})).connectUrl}catch{return null}}async function yu(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await Ut(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:r.connectUrl,state:r.token}):Br(e.pluginId,r.connectUrl)}catch{return`[auth-missing:${e.pluginId}:${e.authType}] Authentication required. Could not create connect link. Check hub configuration and server logs.`}let t=await fu({manual:e.manual,hub:e.hub},{plugin:e.plugin,tenantId:e.tenantId,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return t?Br(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function mu(e,n,t){let r=$e(Ce(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString();return n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):Br(e,i)}async function hu(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&qe(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?mu(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?yu({manual:e.manual,hub:e.hub,plugin:e.plugin,pluginId:t,tenantId:n,authType:e.error.authType,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy}):e.error.message}async function Di(e){let n=await hu(e);throw new W(e.error.pluginId,e.error.authType,n)}var ku=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Oi(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(o).find(l=>o[l]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||ku)(e,i)}function bu(e){return typeof e=="function"}function Lr({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:d,manualConfig:g,hubConfig:f,plugin:y,kek:m,allPlugins:h,multiTenancy:b}){for(let[C,S]of Object.entries(e)){let x=n?.[C];if(bu(S)){let E=x,k=[...s,C].join("."),T=async(v={})=>{let j=l?.[k];qt(k,j?.riskLevel??"write");let re;if(u){let K=j,{result:Tn,reason:Q,onComplete:nn,token:oe,id:xe,expiresAt:q}=await ti({pluginId:o,endpointPath:k,args:v,mode:u.mode,override:u.overrides?.[k],riskLevel:K?.riskLevel??"write",meta:K,db:c,timeoutMs:p?Zt(p.timeout):void 0,tenantId:d,approvalMode:p?.mode});if(Tn==="blocked"){let X;throw Q==="denied"?X=`Action '${k}' was denied by the user. Await further instructions before proceeding.`:Q==="policy"?X=`Action '${k}' is blocked by the permission policy. Update the corsair config to allow it.`:Q==="timeout"?X=`Action '${k}' timed out waiting for approval.`:oe&&xe?X=await jt({permissionsOptions:p,manual:g,hub:f,permissionId:xe,permissionToken:oe,plugin:o,endpoint:k,args:v,tenantId:d??"default",expiresAt:q??new Date(Date.now()+(p?Zt(p.timeout):600*1e3)).toISOString(),operationPath:k}):X=`Action '${k}' requires user approval before it can run.`,new Ze(X)}re=nn}let P=async(K,Tn,Q)=>{try{return await S(Tn,Q)}catch(nn){if(nn instanceof Error){let oe=await Oi(nn,o,k,typeof Q=="object"&&Q!==null?Q:{args:Q},i);if(K<(oe.maxRetries||0)){let xe=K+1;console.log(`Retrying (${xe} / ${oe.maxRetries})...`);let q;if(oe.headersRetryAfterMs)q=oe.headersRetryAfterMs;else switch(oe.retryStrategy){case"exponential_backoff":q=Math.pow(2,xe-1)*1e3;break;case"exponential_backoff_jitter":let X=Math.pow(2,xe-1)*1e3,hs=(Math.random()-.5)*1e3;q=Math.max(0,X+hs);break;case"linear_1s":q=1e3;break;case"linear_2s":q=2e3;break;case"linear_3s":q=3e3;break;case"linear_4s":q=4e3;break;default:q=1e3;break}await new Promise(X=>setTimeout(X,q)),await P(xe,Tn,Q),console.log(`[corsair:${o}:${k}] Retry strategy:`,oe)}}throw nn}},Y;try{Y=a?await a(t,"endpoint"):void 0}catch(K){throw K instanceof W&&(y&&f&&pn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:d,verified:!1}),await Di({error:K,manual:g,hub:f,plugin:y,tenantId:d,database:c,kek:m,plugins:h,multiTenancy:b})),K}if(!E?.before&&!E?.after){let K=await P(0,{...t,key:Y},v);return await re?.(),y&&f&&pn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:d,verified:!0}),K}let en={...t,key:Y},Ae=E.before?await E.before(en,v):{ctx:en,args:v,continue:!0,passToAfter:void 0};if(Ae.continue===!1)return;let no=await P(0,Ae.ctx,Ae.args);return await E.after?.(Ae.ctx,no,Ae.passToAfter),await re?.(),y&&f&&pn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:d,verified:!0}),no};r[C]=T}else if(S&&typeof S=="object"){let E={};Lr({endpoints:S,hooks:x,ctx:t,tree:E,pluginId:o,errorHandlers:i,currentPath:[...s,C],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:d,manualConfig:g,hubConfig:f,plugin:y,kek:m,allPlugins:h,multiTenancy:b}),r[C]=E}}}function Mi(e){return e&&typeof e=="object"?e:{}}async function Hi(e,n){let t=new URLSearchParams({tenantId:n.tenantId});return n.limit!=null&&t.set("limit",String(n.limit)),$({hub:e,path:`/runs?${t.toString()}`,parseResponse:r=>{let o=Mi(r).runs;return Array.isArray(o)?o:[]}})}async function Nr(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Mi(t).run})}async function $r(e,n,t){await _({hub:e,path:`/runs/${encodeURIComponent(t.runId)}/${n}?tenantId=${encodeURIComponent(t.tenantId)}`,body:{},notFoundMessage:`Run "${t.runId}" cannot be ${n==="cancel"?"canceled":`${n}d`} in its current state`,parseResponse:r=>r})}var Fi=(e,n)=>$r(e,"approve",n),Ui=(e,n)=>$r(e,"deny",n),Bi=(e,n)=>$r(e,"cancel",n);function Li(e,n){let t=()=>{if(!e)throw new Error("corsair.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o=>({get:()=>Nr(t(),{runId:o,tenantId:n}),approve:()=>Fi(t(),{runId:o,tenantId:n}),deny:()=>Ui(t(),{runId:o,tenantId:n}),cancel:()=>Bi(t(),{runId:o,tenantId:n})}));return r.list=o=>Hi(t(),{tenantId:n,limit:o?.limit}),r.get=o=>Nr(t(),{runId:o,tenantId:n}),r}function Ni(e,n){let t=()=>{if(!e)throw new Error("corsair.threads requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o=>({message:i=>Fr(t(),{threadId:o,tenantId:n,message:i}),listMessages:()=>ht(t(),{threadId:o,tenantId:n})}));return r.create=o=>Hr(t(),{tenantId:n,message:o}),r.list=()=>Ur(t(),{tenantId:n}),r.listMessages=o=>ht(t(),{threadId:o,tenantId:n}),r}function wu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Wr({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(wu(s)){let u=a,l=async c=>{let p=(g,f)=>s.handler(g,f),d=o?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?p({...t,key:d},c):(async()=>{let g={...t,key:d},f=u.before?await u.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let y=await p(f.ctx,f.args);return y?.success===!0&&await u.after?.(f.ctx,y,f.passToAfter),y})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let u={};Wr({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function Cu(e){return e&&typeof e=="object"?e:{}}async function $i(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Cu(t).workflows;return Array.isArray(r)?r:[]}})}async function Wi(e,n){return _({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/run?tenantId=${encodeURIComponent(n.tenantId)}`,body:{payload:n.payload,idempotencyKey:n.idempotencyKey},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}function ji(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o=>({run:i=>Wi(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey})}));return r.list=()=>$i(t(),{tenantId:n}),r}function Tu(e,n,t,r){let o=null;return async()=>{if(o)return o;if(!e)throw new Error("Database not configured");let{accountId:i}=await Ei({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function vu(e,n,t,r,o){return e?At(e.db,n,t,r,o):{findByEntityId:async()=>null,existsByEntityId:async()=>!1,findIdByEntityId:async()=>null,findById:async()=>null,findManyByEntityIds:async()=>[],list:async()=>[],search:async()=>[],upsertByEntityId:async()=>{throw new Error("Database not configured")},deleteById:async()=>!1,deleteByEntityId:async()=>!1,count:async()=>0}}function jr(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",p=l&&t?()=>Ne(l,c):void 0,d={},g={};for(let f of e)d[f.id]={},g[f.id]={};for(let f of e){let y=f.schema,m=Tu(t,f.id,c,p);if(y?.entities){let P={};for(let[Y,en]of Object.entries(y.entities)){let Ae=t?At(t.db,m,Y,y.version,en):vu(void 0,m,Y,y.version,en);P[Y]=Ae}g[f.id].db=P,d[f.id].db=P}let h=f.options,b=f.authConfig,C;if(t&&o&&h?.authType){let P=b?.[h.authType]?.account??[];C=D({authType:h.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:P,ensureProvisioned:p}),d[f.id].keys=C}let S={database:t,db:g[f.id]?.db??{},$getAccountId:m,...f.options?{options:f.options}:{},...C?{keys:C,authType:h?.authType}:{},tenantId:c,...u?{hub:u}:{}},x=f.endpoints??{},E=f.hooks,k={...i,...f.errorHandlers},T={},v=f.options?.permissions;Lr({endpoints:x,hooks:E,ctx:S,tree:T,pluginId:f.id,errorHandlers:k,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:v,endpointMeta:f.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:f.oauthConfig,kek:o,tenantId:c}:void 0,hubConfig:u,plugin:f,kek:o,allPlugins:e,multiTenancy:l?.multiTenancy}),Object.keys(T).length>0&&(d[f.id].api=T),S.endpoints=T;let j=f.webhooks??{},re=f.webhookHooks;if(Object.keys(j).length>0){let P={};Wr({webhooks:j,hooks:re,ctx:S,webhooksTree:P,keyBuilder:f.keyBuilder}),d[f.id].webhooks=P,f.pluginWebhookMatcher&&(d[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(d[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return d.threads=Ni(u,c),d.runs=Li(u,c),d.workflows=ji(u,c),d}function Ki(e,n,t){let r={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],u=O({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=u}}return r}var Pu="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function qi(e){let{permissions:n,approval:t}=e;if(n&&t)throw new Error("createCorsair was given both permissions and approval config. Use permissions only \u2014 approval is deprecated.");return t?(console.warn(`[corsair] ${Pu}`),t):n}var Zi=[{method:"GET",pattern:"/ok",handler:async()=>M(200,zn())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>M(200,await Je(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>M(201,await Qn(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>M(200,await Yn(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>M(200,await Ge(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>M(200,await Vn(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>M(200,await Xn(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>M(200,await Gt(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?M(200,await zt(e,t)):M(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>M(200,await et(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>M(200,await nt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>M(200,await tt(e,n,t))}];(()=>{let e=new Set;for(let n of Zi){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Au(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let o={};for(let i=0;i<t.length;i++){let s=t[i],a=r[i];if(s.startsWith(":"))o[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return o}function xu(e,n){if(!n)return e;let t=n.endsWith("/")?n.slice(0,-1):n;return e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length):e}async function Ru(e){if(!(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json")))try{let t=await e.text();return t?JSON.parse(t):void 0}catch{throw new I(400,"invalid_json","Request body is not valid JSON")}}var Iu="/api/corsair";function Me(e,n={}){let t=n.basePath??Iu,r=w(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async o=>{try{let i=new URL(o.url),s=xu(i.pathname,t),a=o.method.toUpperCase();if(a==="OPTIONS"||s==="/"||s==="")return await Oe(e,o);if(a!=="GET"&&a!=="POST")return M(405,{error:"method_not_allowed",message:`Method ${a} not allowed`});let u=Object.fromEntries(i.searchParams);for(let l of Zi){if(l.method!==a)continue;let c=Au(l.pattern,s);if(!c)continue;let p=await Ru(o);return await l.handler({corsair:e,internal:r,req:o,params:c,query:u,body:p})}throw Te(`No route for ${a} ${s}`)}catch(i){if(n.onError){let a=await n.onError(i,o);if(a)return a}if(i instanceof I)return ri(i);let s=i instanceof Error?i.message:"Internal server error";return M(500,{error:"internal_error",message:s})}}}function Su(e){let n=e.get?.("host")??"localhost",t=e.protocol??"http",r=e.originalUrl??e.url,o=`${t}://${n}${r}`,i=new Headers;for(let[u,l]of Object.entries(e.headers))if(l!=null)if(Array.isArray(l))for(let c of l)i.append(u,c);else i.set(u,l);let s=e.method!=="GET"&&e.method!=="HEAD",a={method:e.method,headers:i};return s&&e.body!==void 0&&(a.body=typeof e.body=="string"?e.body:JSON.stringify(e.body),i.has("content-type")||i.set("content-type","application/json")),new Request(o,a)}async function _u(e,n){e.status(n.status),n.headers.forEach((r,o)=>e.setHeader(o,r));let t=Buffer.from(await n.arrayBuffer());e.send(t)}function Gi(e,n){let t=Me(e,n);return async(r,o,i)=>{try{let s=await t(Su(r));await _u(o,s)}catch(s){i(s)}}}function Ji(e,n){let t=Me(e,n);return r=>t(r.req.raw)}function zi(e,n){let t=Me(e,n);return{GET:t,POST:t,OPTIONS:t}}function Vi(e){let n={[wn]:e};return{ok:zn,tenants:{list:()=>Je(e),create:t=>Qn(e,t),get:t=>Yn(e,t)},plugins:{list:()=>Ge(e),get:t=>Vn(e,t)},connectionStatus:{get:t=>Xn(e,t?.tenantId)},permissions:{get:t=>ci(e,t)},connect:{createLink:t=>et(n,e,t),resolve:t=>nt(n,e,t),oauthCallback:t=>tt(n,e,t)}}}async function Yi(e,n,t,r,o="pending"){if(!e)return null;try{let i=ao(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function Eu(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Yi(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Xi from"https";import*as bt from"querystring";var Du=["expires_in","refresh_token_expires_in"];function Qi(e){let n={...e};for(let t of Du){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function Ou(e){try{return Qi(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=bt.parse(e);return!n.access_token&&!n.error?null:Qi({...n})}function $n(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,u)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(l.client_id=n,l.client_secret=t);let c=bt.stringify(l),p={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(p.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let d=Xi.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:p},g=>{let f="";g.on("data",y=>{f+=y}),g.on("end",()=>{if(g.statusCode!==200){u(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let y=Ou(f);y?a(y):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});d.on("error",g=>u(new Error(`Request failed: ${g.message}`))),d.write(c),d.end()})}var es=" ";function z(e){let n=e;return n._def??n.def??{}}function V(e){let n=e.typeName;if(n)return n;let t=e.type;if(t)return`Zod${t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}`}function J(e){return e.innerType??e.schema??e.out??e.in}function ts(e,n){switch(n){case"ZodPipe":return e.in??e.innerType;case"ZodEffects":return e.schema??e.innerType;case"ZodTransform":return e.schema??e.innerType??e.in;default:return J(e)}}function rs(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Ct(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function Qe(e){return Array.isArray(e.options)?e.options:Array.isArray(e.values)?e.values:e.entries!==null&&typeof e.entries=="object"&&!Array.isArray(e.entries)?Object.values(e.entries):[]}function os(e,n){return e.description??n.description}function Mu(e){let n=e;for(;n;){let t=z(n),r=os(n,t);if(r)return r;let o=V(t);if(Jr(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=ts(t,o);continue}break}}function Jr(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function L(e){let n=z(e),t=V(n);switch(t){case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"Date";case"ZodNull":return"null";case"ZodUnknown":case"ZodAny":return"any";case"ZodLiteral":return String(n.value??Qe(n)[0]??"unknown");case"ZodEnum":return Qe(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=J(n);return r?L(r):"unknown"}case"ZodNullable":{let r=J(n);return`${r?L(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=J(n);return r?L(r):"unknown"}case"ZodArray":{let r=rs(n);if(!r)return"unknown[]";let o=z(r),i=V(o)==="ZodUnion",s=L(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Ct(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let u=V(z(a));return`${u==="ZodOptional"||u==="ZodNullable"?s+"?":s}: ${L(a)}`}).join(", ")} }`}case"ZodUnion":return Qe(n).map(r=>L(r)).join(" | ");case"ZodIntersection":return`${L(n.left)} & ${L(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=ts(n,t);return r?L(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function ge(e){let n=z(e),t=V(n),r=os(e,n);switch(t){case"ZodString":return{kind:"string",optional:!1,description:r};case"ZodNumber":return{kind:"number",optional:!1,description:r};case"ZodBoolean":return{kind:"boolean",optional:!1,description:r};case"ZodLiteral":{let o=n.value??Qe(n)[0],i=typeof o=="string"||typeof o=="number"||typeof o=="boolean"?o:String(o??"");return{kind:"literal",optional:!1,description:r,value:i}}case"ZodEnum":{let o=Qe(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=J(n),i=o?ge(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=J(n),i=o?ge(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=J(n);return o?{...ge(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=rs(n);return{kind:"array",optional:!1,description:r,items:o?ge(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Ct(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=ge(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=Qe(n);for(let i of o){let s=z(i);if(V(s)==="ZodObject")return{...ge(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=J(n);return o?{...ge(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function Wy(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let o=t.slice(0,r),i=t.slice(r+1),s=e.find(c=>c.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Pe(s.endpointMeta,a),l=Pe(s.endpointSchemas,a);return!u&&!l?null:{input:l?.input?ge(l.input):null,output:l?.output?ge(l.output):null,description:u?.description}}var zr=["equals","contains","startsWith","endsWith","in"],Hu=["equals","gt","gte","lt","lte","in"],Fu=["equals"],Uu=["equals","before","after","between"];function is(e){let n=z(e);switch(V(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=J(n);return r?is(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Vr(e){let n=z(e),t=V(n);if(Jr(t)){let i=J(n);return i?Vr(i):{}}if(t!=="ZodObject")return{};let r=Ct(e,n),o={};for(let[i,s]of Object.entries(r)){let a=is(s);a==="string"?o[i]={type:"string",operators:zr}:a==="number"?o[i]={type:"number",operators:Hu}:a==="boolean"?o[i]={type:"boolean",operators:Fu}:a==="date"&&(o[i]={type:"date",operators:Uu})}return o}function ss(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function qr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];typeof o=="function"?t.push(i.join(".")):o!==null&&typeof o=="object"&&qr(o,i,t)}}function Zr(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Gr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Zr(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Gr(o,i,t)}}function Yr(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!o)return null;let[i,s]=o;if(r.length===0)return Zr(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Zr(s)){let a=Yr(s,r);if(a!==null)return[i,...a]}return null}function as(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);t.push(`${s}${n[i]}: {`)}let r=" ".repeat(n.length+2),o=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${o}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
50
|
+
`)}var Bu=new Set(Pn);function He(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(a=>a.id===r);if(!i)return Bu.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:He(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return Gr(i.webhooks,[],a),a.map(u=>`${i.id}.webhooks.${u}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(u=>`${i.id}.db.${u}.search`):[]}if(!i.endpoints)return[];let s=[];return qr(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];Gr(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(t==="db")for(let i of e){let s=i.schema?.entities;s&&(o[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];qr(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Pe(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function Lu(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function Kr(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
51
|
+
${e.join(", ")}`:`${n}:
|
|
52
|
+
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
53
|
+
`)}function jy(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let c=i.slice(3),p=c.lastIndexOf(".");if(p!==-1){let d=c.slice(0,p),g=c.slice(p+1),f=s.schema?.entities;if(g==="search"&&f){let y=ss(f,d);if(y){let[m,h]=y,b=Vr(h),C=[`Search ${o} ${m} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${zr.join(", ")}]`];for(let[S,x]of Object.entries(b))C.push(` ${S}?: ${x.type} [${x.operators.join(", ")}]`);return C.push("}"),C.join(`
|
|
54
|
+
`)}}}return Kr(He(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let p=Yr(s.webhooks,c.split("."));if(p!==null){let d=p.join("."),g=Pe(s.webhookSchemas,d.toLowerCase()),f=g?.response?L(g.response):null,y=[];return g?.description&&y.push(g.description),g?.payload&&y.push(`payload ${wt(Xe(g.payload))}`),f&&y.push(`response: ${f}`),y.push(`usage:
|
|
55
|
+
${as(o,p)}`),y.join(`
|
|
56
|
+
|
|
57
|
+
`)}}return Kr(He(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Pe(s.endpointMeta,a),l=Pe(s.endpointSchemas,a);if(u||l){let c=[],p=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),d=[u?.description,p].filter(Boolean).join(" ");return d&&c.push(d),l?.input&&c.push(`input ${wt(Xe(l.input))}`),l?.output&&c.push(`output ${wt(Xe(l.output))}`),c.join(`
|
|
58
|
+
|
|
59
|
+
`)}}}return Kr(He(e),"Path not found. Available operations")}function ns(e){let n=e;for(;;){let t=z(n),r=V(t);if(Jr(r)){let o=J(t);if(!o)return n;n=o;continue}return n}}function Xe(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=ns(e),t=z(n);if(V(t)==="ZodObject"){let o=Ct(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=z(a),l=V(u),c=l==="ZodOptional"||l==="ZodNullable",p=ns(a),d=Mu(a);i.push({key:s,optional:c,type:L(p),...d!==void 0?{description:d}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:L(n)}}function wt(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=es.repeat(n+1),r=es.repeat(n);return`{
|
|
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
|
+
`)}
|
|
62
|
+
${r}}`}return"unknown"}function Nu(e,n){let t=He(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:p,lookupKey:d}=Lu(c,n),g=Pe(r.endpointMeta,d),f=Pe(r.endpointSchemas,d);!g&&!f||o.push({path:c,shortPath:p,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:Xe(f?.input),output:Xe(f?.output)})}o.sort((c,p)=>c.path.localeCompare(p.path));let i=[],s=He(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let d=c.toLowerCase().slice(n.length+1),g=d.startsWith(".")?d.slice(1):d;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),y=Yr(r.webhooks,f.split("."));if(y===null)continue;let m=y.join("."),h=Pe(r.webhookSchemas,m.toLowerCase()),b=h?.response?L(h.response):void 0;i.push({path:c,description:h?.description,payload:Xe(h?.payload),responseType:b,usageExample:as(n,y)})}i.sort((c,p)=>c.path.localeCompare(p.path));let a=[],u=He(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let d=c.toLowerCase().slice(n.length+1),g=d.startsWith(".")?d.slice(1):d;if(!g.startsWith("db."))continue;let f=g.slice(3),y=f.lastIndexOf(".");if(y===-1)continue;let m=f.slice(0,y);if(f.slice(y+1)!=="search")continue;let b=ss(l,m);if(!b)continue;let[C,S]=b,x=Vr(S),E=Object.entries(x).map(([k,T])=>({field:k,type:T.type,operators:T.operators}));a.push({path:c,entityName:C,filters:[{field:"entity_id",type:"string",operators:zr},...E]})}return a.sort((c,p)=>c.path.localeCompare(p.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as us}from"crypto";async function $u(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=us(),o=us(),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 Wu}from"crypto";var Tt="https://graph.microsoft.com/v1.0",Qr=2e4,ju=60;async function Ku(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Tt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Qr)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(p=>p.notificationUrl===n.webhookUrl);await Promise.all(c.map(p=>fetch(`${Tt}/subscriptions/${p.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Qr)}).catch(()=>{})))}}catch{}let o=Wu(),i=new Date(Date.now()+ju*6e4).toISOString(),s=await fetch(`${Tt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Qr),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 cs(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function qu(e,n){let t=cs(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 Zu(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ls(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ds(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 Cn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function Gu(e){return Cn(e.body)}function ps(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return vt(Array.isArray(r)?r:[r])}function gs(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=vt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=ps({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 d=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(d?.trim())return d.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Cn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return vt([s?.validationToken])??null}function Ju(e){if(gs(e))return!0;let n=Cn(e.body??e.payload);return ls(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function vt(e){for(let n of e){let t=ds(n);if(t)return t}}function zu(e){let t=Cn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var wn=Symbol.for("corsair:internal");function fs(e){let n=e.database?to(e.database):void 0,t=n&&e.kek?Ki(e.plugins,n,e.kek):kt(!!n,!!e.kek),r=qi(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?xn(e.hub):void 0},i=ni(n),s=Vi(o);if(e.multiTenancy)return Object.assign({withTenant:u=>{if(!u)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let l=jr(e.plugins,{database:n,tenantId:u,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign(l,{[wn]:o})},keys:t,permissions:i,manage:s},{[wn]:o});let a=jr(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign({},a,{keys:t,permissions:i,manage:s,[wn]:o})}var Vu={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:{}}}},Xr=Vu;async function Wn(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=oo(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=uc(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await dc(c,i);let p=await pc(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await yc(e,u,n.credentials,l,o,i);let d=await hc(p,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=fs({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await kc(g,a.plugins,d,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function eo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...F[n][t],...r])}function ac(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=R(o);if(!i)continue;let s=eo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function uc(e,n,t){let r=io(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&&ac(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 ms(e,n){return fe(e)?n===0?!0:Object.values(e).every(t=>ms(t,n-1)):!1}function cc(e){return ms(e,4)}var lc={...uo};function Pt(e){if(e instanceof tc){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof sc?Pt(r):"unknown";return n}return e instanceof ec?`${Pt(e.unwrap())} | null`:e instanceof rc?`${Pt(e.unwrap())} | undefined`:e instanceof Xu?e.options.join(" | "):e instanceof ic?"string":e instanceof nc?"number":e instanceof Yu?"boolean":e instanceof Qu?"date":e instanceof oc?"jsonb":"unknown"}async function dc(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(lc))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(Pt(i),null,2)}`)}async function pc(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=R(a),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let y=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:y,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",y).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let p=l?a.authConfig?.[l]?.integration??[]:[],d=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?O({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:p}):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 y=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!y){let m=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:m,tenant_id:t,integration_id:c.id,config:{},created_at:i,updated_at:i}).execute(),y=await e.selectFrom("corsair_accounts").selectAll().where("id","=",m).executeTakeFirst(),o(`[corsair:setup] Created account: ${u}`)}f=y&&D({authType:l,integrationName:u,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:d}),y&&f&&!y.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:[...F[l].integration,...p],accountFields:r?[...F[l].account,...d]:[]})}return s}function gc(e){if(!fe(e))return;let n=e.keys;return fe(n)?n:void 0}function fc(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function yc(e,n,t,r,o,i){let s=gc(e),a=n.provisionAccounts?fc(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(h=>h.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let p=R(c);if(!p){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let d=eo(c,p,"integration"),g=eo(c,p,"account"),f=s?.[u],y=a?.[u],m=fe(y)?y.keys:void 0;for(let[h,b]of Object.entries(l))if(b){if(d.has(h)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${u}.${h}' 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 C=N(f,`set_${h}`);if(!C){i(`[corsair:setup] Cannot set integration field '${h}' for '${u}'.`);continue}await C(b),o(`[corsair:setup] Set ${u} integration.${h}`);continue}if(g.has(h)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${h}' on a multi-tenant instance`);let C=N(m,`set_${h}`);if(!C){i(`[corsair:setup] Cannot set account field '${h}' for '${u}'.`);continue}await C(b),o(`[corsair:setup] Set ${u} account.${h} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${h}' for plugin '${u}'.`)}}}var ys=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function mc(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let d of o){if(ys.has(d))continue;let g=N(t,`get_${d}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||l.push(d)}if(r&&i.length>0)for(let d of i){if(ys.has(d))continue;let g=N(r,`get_${d}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||c.push(d)}let p=l.length===0&&c.length===0;if(p)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 d=[...l,...c];if(u==="cli"){let g=d.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
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 y=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${y}.keys.set_${f}(value)`)}a(g.join(`
|
|
66
|
+
`))}}return p}async function hc(e,n,t,r){let o=new Set;for(let i of e.values())await mc(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function kc(e,n,t,r,o){if(!cc(Xr)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Xr,s=new Set(n.map(a=>a.id));for(let[a,u]of Object.entries(i)){if(!s.has(a))continue;if(!t.has(a)){r(`[corsair:setup] Skipping backfill for '${a}' \u2014 auth not configured.`);continue}let l=fe(e)?e[a]:void 0,c=fe(l)?l.api:void 0;if(c)for(let[p,d]of Object.entries(u))for(let[g,f]of Object.entries(d)){r(`[corsair:setup] Backfilling ${a} \u203A ${p}.${g}...`);try{let y=fe(c)?c[p]:void 0;await N(y,g)?.(f)}catch(y){o(`[corsair:setup] ${a} \u203A ${p}.${g} failed: `+(y instanceof Error?y.message:String(y)))}}}}export{lo as a,ye as b,Rt as c,tn as d,po as e,go as f,me as g,Re as h,ie as i,Ue as j,Be as k,he as l,St as m,yo as n,sn as o,se as p,xn as q,H as r,Rn as s,Le as t,In as u,Sn as v,_n as w,En as x,ho as y,Dn as z,ke as A,ae as B,ue as C,Z as D,Et as E,un as F,be as G,ce as H,cn as I,O as J,D as K,Ro as L,Io as M,Wn as N,yc as O,Ce as P,Ot as Q,We as R,je as S,Ht as T,Ln as U,Bo as V,_e as W,B as X,Ft as Y,gn as Z,Wo as _,na as $,jn as aa,Xl as ba,qo as ca,Zo as da,Go as ea,Ut as fa,Kn as ga,zo as ha,Vo as ia,Bt as ja,qn as ka,Zn as la,Ze as ma,Jn as na,Kt as oa,ei as pa,qt as qa,Yt as ra,Qt as sa,rt as ta,Xt as ua,ze as va,Ve as wa,ot as xa,it as ya,fn as za,er as Aa,nr as Ba,st as Ca,yn as Da,at as Ea,ut as Fa,ve as Ga,Ye as Ha,yi as Ia,sr as Ja,ar as Ka,De as La,kn as Ma,bn as Na,mt as Oa,lr as Pa,dr as Qa,fr as Ra,yr as Sa,mr as Ta,hr as Ua,kr as Va,Oe as Wa,W as Xa,br as Ya,xi as Za,Ri as _a,wr as $a,Cr as ab,Tr as bb,vr as cb,Pr as db,Ar as eb,xr as fb,Rr as gb,Ir as hb,Sr as ib,_r as jb,Er as kb,Dr as lb,Or as mb,Mr as nb,Me as ob,Gi as pb,Ji as qb,zi as rb,Yi as sb,Eu as tb,$n as ub,Wy as vb,He as wb,jy as xb,wt as yb,Nu as zb,$u as Ab,Tt as Bb,Ku as Cb,cs as Db,qu as Eb,Zu as Fb,ls as Gb,ds as Hb,Cn as Ib,Gu as Jb,ps as Kb,gs as Lb,Ju as Mb,vt as Nb,zu as Ob,wn as Pb,fs as Qb};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-
|
|
2
|
-
export { f as PermissionLookupInput } from '../../types-
|
|
3
|
-
import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-
|
|
1
|
+
import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-DfIEIfeF.js';
|
|
2
|
+
export { f as PermissionLookupInput } from '../../types-DfIEIfeF.js';
|
|
3
|
+
import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-Ce3Ii8Xs.js';
|
|
4
4
|
import '../../index-eydqYIn0.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ea as a,fa as b,ga as c}from"./chunk-
|
|
1
|
+
import{ea as a,fa as b,ga as c}from"./chunk-AIDBRYAC.js";import"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|
package/dist/core.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-
|
|
1
|
+
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-Down-zOl.js';
|
|
2
2
|
import { CorsairDatabase } from './db.js';
|
|
3
|
-
import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-
|
|
4
|
-
export { g as AccountFieldNames, k as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, h as BaseKeyManager, M as BeforeHookResult, n as BindEndpoints,
|
|
5
|
-
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, g as PermissionRequiredError, P as PluginDocsIntrospection, k as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, l as asRecord, h as collectPluginWebhookMatchers, n as decodePubSubData, o as extractMicrosoftGraphValidationToken, p as firstString, f as formatDocSchemaShape, q as getHeader, i as introspectPluginForDocs, s as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, j as matchWebhookPluginAndTenant, t as readBodyRecord, u as readQueryParam, r as resolveConnectLink, v as toExternalId } from './tenant-match-utils-
|
|
6
|
-
import { A as AuthTypes } from './types-
|
|
7
|
-
export { g as AllProviders, B as BaseProviders, h as PickAuth, j as ProviderDisplayNames, i as formatProviderDisplayName } from './types-
|
|
3
|
+
import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-DU9NOasm.js';
|
|
4
|
+
export { g as AccountFieldNames, a6 as AgentReply, k as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, h as BaseKeyManager, M as BeforeHookResult, n as BindEndpoints, ae as BindWebhooks, ac as Bivariant, o as BoundEndpointFn, p as BoundEndpointTree, af as BoundWebhook, ag as BoundWebhookTree, m as CorsairClient, q as CorsairContext, r as CorsairEndpoint, t as CorsairErrorHandler, c as CorsairIntegration, N as CorsairKeyBuilder, Q as CorsairKeyBuilderBase, ah as CorsairOAuthWebhookTenantLinkResolver, z as CorsairPermissionsNamespace, C as CorsairPlugin, S as CorsairPluginContext, U as CorsairPluginSubscribe, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, a7 as CorsairThreadsNamespace, ai as CorsairWebhook, aj as CorsairWebhookHandler, ak as CorsairWebhookMatcher, al as CorsairWebhookTenantMatcher, a8 as CreateThreadResult, V as EndpointHooks, X as EndpointMetaEntry, E as EndpointPathsOf, Y as EndpointRiskLevel, s as EndpointTree, D as EnforcePermissionOptions, F as EnforcePermissionResult, u as ErrorContext, v as ErrorHandler, w as ErrorHandlerAndMatchFunction, x as ErrorMatcher, i as IntegrationFieldNames, Z as KeyBuilderContext, j as OAuth2IntegrationCredentials, O as OAuthConfig, _ as PermissionMode, $ as PermissionPolicy, P as PluginAuthConfig, a0 as PluginEndpointMeta, a1 as PluginPermissionsConfig, am as RawWebhookRequest, K as ReadonlyForbiddenError, a2 as RequiredPluginEndpointMeta, a3 as RequiredPluginEndpointSchemas, a4 as RequiredPluginWebhookSchemas, R as RetryStrategies, y as RetryStrategy, a9 as ThreadHandle, aa as ThreadMessage, ab as ThreadSummary, T as TokenResponse, ad as UnionToIntersection, a5 as WebhookHooks, an as WebhookPathsOf, ao as WebhookRequest, ap as WebhookResponse, W as WebhookTenantMatch, aq as WebhookTree, G as assertReadonlyAllowed, l as exchangeCodeForTokens, J as isReadonlyScopeActive, L as runReadonly } from './index-DU9NOasm.js';
|
|
5
|
+
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, g as PermissionRequiredError, P as PluginDocsIntrospection, k as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, l as asRecord, h as collectPluginWebhookMatchers, n as decodePubSubData, o as extractMicrosoftGraphValidationToken, p as firstString, f as formatDocSchemaShape, q as getHeader, i as introspectPluginForDocs, s as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, j as matchWebhookPluginAndTenant, t as readBodyRecord, u as readQueryParam, r as resolveConnectLink, v as toExternalId } from './tenant-match-utils-BIM8e0pe.js';
|
|
6
|
+
import { A as AuthTypes } from './types-DfIEIfeF.js';
|
|
7
|
+
export { g as AllProviders, B as BaseProviders, h as PickAuth, j as ProviderDisplayNames, i as formatProviderDisplayName } from './types-DfIEIfeF.js';
|
|
8
8
|
import 'kysely';
|
|
9
9
|
import './index-eydqYIn0.js';
|
|
10
10
|
import 'zod';
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ab as
|
|
1
|
+
import{Ab as B,B as d,Bb as C,C as e,Cb as D,D as f,Db as E,E as g,Eb as F,F as h,Fb as G,G as i,Gb as H,H as j,Hb as I,I as k,Ib as J,J as l,Jb as K,K as m,Kb as L,L as n,Lb as M,M as o,Mb as N,Nb as O,Ob as P,Pb as Q,Qb as R,Xa as v,a,b,ja as p,ma as q,na as r,oa as s,pa as t,qa as u,sb as w,tb as x,ub as y,yb as z,zb as A}from"./chunk-AIDBRYAC.js";import{h as c}from"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{v as AuthMissingError,c as BASE_AUTH_FIELDS,Q as CORSAIR_INTERNAL,C as MS_GRAPH_API_BASE,q as PermissionRequiredError,a as ProviderDisplayNames,r as ReadonlyForbiddenError,J as asRecord,u as assertReadonlyAllowed,G as collectPluginWebhookMatchers,m as createAccountKeyManager,R as createCorsair,l as createIntegrationKeyManager,P as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,y as exchangeCodeForTokens,M as extractMicrosoftGraphValidationToken,O as firstString,z as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,H as getHeader,B as googleChannelSubscribe,o as initializeAccountDEK,n as initializeIntegrationDEK,A as introspectPluginForDocs,N as isMicrosoftGraphValidationHandshake,t as isReadonlyScopeActive,w as logEvent,x as logEventFromContext,E as matchWebhookPlugin,F as matchWebhookPluginAndTenant,D as msGraphSubscribe,k as reEncryptConfig,K as readBodyRecord,L as readQueryParam,p as resolveConnectLink,s as runReadonly,I as toExternalId};
|
package/dist/hub.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { A as AuthTypes } from './types-
|
|
2
|
-
export { i as formatProviderDisplayName } from './types-
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
7
|
-
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-
|
|
1
|
+
import { A as AuthTypes } from './types-DfIEIfeF.js';
|
|
2
|
+
export { i as formatProviderDisplayName } from './types-DfIEIfeF.js';
|
|
3
|
+
import { as as HubOAuthMode, at as HubConnectSessionResult, au as HubPermissionSessionResult, H as HubConfig, av as HubConfigInput, aw as HubConnectSessionInput, ax as HubListProjectConnectionsInput, A as AccountKeyManagerFor, ay as HubPermissionSessionInput } from './index-DU9NOasm.js';
|
|
4
|
+
export { az as DEFAULT_HUB_API_URL, aA as HubEnvironmentSlug } from './index-DU9NOasm.js';
|
|
5
|
+
import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-BfatdOwQ.js';
|
|
6
|
+
export { n as BROWSER_DELIVERY_TTL_MS, o as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, j as TunnelEnvelope } from './index-BfatdOwQ.js';
|
|
7
|
+
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-DSOMrzVq.js';
|
|
8
8
|
import './index-eydqYIn0.js';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import './db.js';
|
|
@@ -220,7 +220,19 @@ type ServerDeliveryAckBody = {
|
|
|
220
220
|
sync?: {
|
|
221
221
|
encrypted: string;
|
|
222
222
|
};
|
|
223
|
+
/** Workflow execution outcome returned by `run` deliveries. */
|
|
224
|
+
run?: RunResultPayload;
|
|
225
|
+
/** Read-only script outcome returned by `probe` deliveries. */
|
|
226
|
+
probe?: ProbeResultPayload;
|
|
223
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* Reads the workflow run outcome from a parsed delivery ack body.
|
|
230
|
+
*/
|
|
231
|
+
declare function extractRunFromDeliveryAck(body: ServerDeliveryAckBody): RunResultPayload | null;
|
|
232
|
+
/**
|
|
233
|
+
* Reads the read-only probe outcome from a parsed delivery ack body.
|
|
234
|
+
*/
|
|
235
|
+
declare function extractProbeFromDeliveryAck(body: ServerDeliveryAckBody): ProbeResultPayload | null;
|
|
224
236
|
/**
|
|
225
237
|
* Signs a tunnel envelope for server POST delivery.
|
|
226
238
|
*
|
|
@@ -577,4 +589,4 @@ declare function decodePermissionTokenFromPath(encoded: string): string;
|
|
|
577
589
|
*/
|
|
578
590
|
declare function createSignedTokenJti(): string;
|
|
579
591
|
|
|
580
|
-
export { type ClientBridgeDeliverySpec, type ClientBridgeTransportResult, type ConnectAuthFieldStatus, type ConnectAuthKind, type ConnectAuthStatusLevel, type ConnectCreateLinkDeliveryResult, type ConnectPluginManifestEntry, type ConnectSessionTokenPayload, type ConnectStatusPluginEntry, type ConnectStatusResponse, type ConnectTokenPayload, type CreateConnectSessionRequestBody, type CreatePermissionSessionRequestBody, type FormatServerDeliveryErrorInput, HubConfig, HubConfigInput, HubConnectSessionInput, HubConnectSessionResult, type HubDeliveryRequest, type HubDeliveryResult, HubListProjectConnectionsInput, HubNotConfiguredError, HubOAuthMode, type HubOAuthRefreshResponse, HubPermissionSessionInput, HubPermissionSessionResult, type HubProjectConnection, type ManagedAccessTokenResult, type ManagedAuthContext, ManagedOAuthDeliveryError, type PermissionTokenPayload, type PrepareClientBridgeDeliveryTransportInput, type ProcessManagedOAuthDeliveryOptions, type ProcessManagedOAuthDeliveryResult, type ServerDeliveryAckBody, type SignedDeliveryHeaders, type SignedEnvelopeDeliveryResult, TunnelType, attachManagedRefreshAuth, buildClientBridgeBrowserDeliveryUrl, createConnectSessionJti, createConnectTokenJti, createHubConnectSession, createHubPermissionSession, createHubRouteHandlers, createPermissionSessionJti, createSignedTokenJti, decodeConnectSessionTokenFromPath, decodeConnectTokenFromPath, decodePermissionTokenFromPath, deliverConnectCreateLink, deliverSignedEnvelope, describeDeliveryNetworkError, encodeConnectTokenForPath, extractConnectLinkFromDeliveryAck, extractSyncFromDeliveryAck, formatHubApprovalMessage, formatServerDeliveryError, getConnectSessionExpiryMs, getConnectStatusForTenant, getConnectTokenExpiryMs, getHubConfig, getManagedAccessToken, handleHubDeliveryGet, handleHubDeliveryPost, handleHubDeliveryRequest, hubDeliveryToResponse, inferHubEnvironmentSlug, isLoopbackUrl, isServerDeliveryAckSuccessful, listHubProjectConnections, normalizeHubConfig, parseConnectLinkFromDeliveryBody, parseConnectSessionResponse, parseConnectStatusResponse, parseHubApiErrorBody, parseOAuthRefreshResponse, parsePermissionSessionResponse, parseProjectConnectionsResponse, parseServerDeliveryAckBody, parseSyncFromDeliveryBody, prepareClientBridgeDeliveryTransport, processManagedOAuthDelivery, registerHubWebhookTenantLink, resolveDeliveryTransport, resolveHubDeliveryUrl, resolveHubOAuthCallbackUrl, respondToHubDelivery, respondToHubDeliveryFromRequest, signConnectSessionToken, signConnectToken, signDeliveryEnvelope, signPermissionToken, usesBrowserDelivery, validateProductionDeliveryUrl, verifyConnectSessionToken, verifyConnectToken, verifyDeliveryEnvelope, verifyPermissionToken, verifySignedTunnelDelivery };
|
|
592
|
+
export { type ClientBridgeDeliverySpec, type ClientBridgeTransportResult, type ConnectAuthFieldStatus, type ConnectAuthKind, type ConnectAuthStatusLevel, type ConnectCreateLinkDeliveryResult, type ConnectPluginManifestEntry, type ConnectSessionTokenPayload, type ConnectStatusPluginEntry, type ConnectStatusResponse, type ConnectTokenPayload, type CreateConnectSessionRequestBody, type CreatePermissionSessionRequestBody, type FormatServerDeliveryErrorInput, HubConfig, HubConfigInput, HubConnectSessionInput, HubConnectSessionResult, type HubDeliveryRequest, type HubDeliveryResult, HubListProjectConnectionsInput, HubNotConfiguredError, HubOAuthMode, type HubOAuthRefreshResponse, HubPermissionSessionInput, HubPermissionSessionResult, type HubProjectConnection, type ManagedAccessTokenResult, type ManagedAuthContext, ManagedOAuthDeliveryError, type PermissionTokenPayload, type PrepareClientBridgeDeliveryTransportInput, type ProcessManagedOAuthDeliveryOptions, type ProcessManagedOAuthDeliveryResult, type ServerDeliveryAckBody, type SignedDeliveryHeaders, type SignedEnvelopeDeliveryResult, TunnelType, attachManagedRefreshAuth, buildClientBridgeBrowserDeliveryUrl, createConnectSessionJti, createConnectTokenJti, createHubConnectSession, createHubPermissionSession, createHubRouteHandlers, createPermissionSessionJti, createSignedTokenJti, decodeConnectSessionTokenFromPath, decodeConnectTokenFromPath, decodePermissionTokenFromPath, deliverConnectCreateLink, deliverSignedEnvelope, describeDeliveryNetworkError, encodeConnectTokenForPath, extractConnectLinkFromDeliveryAck, extractProbeFromDeliveryAck, extractRunFromDeliveryAck, extractSyncFromDeliveryAck, formatHubApprovalMessage, formatServerDeliveryError, getConnectSessionExpiryMs, getConnectStatusForTenant, getConnectTokenExpiryMs, getHubConfig, getManagedAccessToken, handleHubDeliveryGet, handleHubDeliveryPost, handleHubDeliveryRequest, hubDeliveryToResponse, inferHubEnvironmentSlug, isLoopbackUrl, isServerDeliveryAckSuccessful, listHubProjectConnections, normalizeHubConfig, parseConnectLinkFromDeliveryBody, parseConnectSessionResponse, parseConnectStatusResponse, parseHubApiErrorBody, parseOAuthRefreshResponse, parsePermissionSessionResponse, parseProjectConnectionsResponse, parseServerDeliveryAckBody, parseSyncFromDeliveryBody, prepareClientBridgeDeliveryTransport, processManagedOAuthDelivery, registerHubWebhookTenantLink, resolveDeliveryTransport, resolveHubDeliveryUrl, resolveHubOAuthCallbackUrl, respondToHubDelivery, respondToHubDeliveryFromRequest, signConnectSessionToken, signConnectToken, signDeliveryEnvelope, signPermissionToken, usesBrowserDelivery, validateProductionDeliveryUrl, verifyConnectSessionToken, verifyConnectToken, verifyDeliveryEnvelope, verifyPermissionToken, verifySignedTunnelDelivery };
|
package/dist/hub.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$a as
|
|
1
|
+
import{$a as ea,A as z,Aa as P,Ba as Q,Ca as R,Da as S,Ea as T,Fa as U,Ga as V,Ha as W,R as A,Ra as X,Sa as Y,Ta as Z,Ua as _,Va as $,Wa as aa,Ya as ba,Za as ca,_a as da,ab as fa,b as a,bb as ga,c as b,cb as ha,d as c,db as ia,e as d,eb as ja,f as e,fb as ka,g as f,ga as B,gb as la,h as g,ha as C,hb as ma,i as h,ia as D,ib as na,j as i,jb as oa,k as j,ka as E,kb as pa,l as k,la as F,lb as qa,m as l,mb as ra,n as m,nb as sa,o as n,p as o,q as p,r as q,ra as G,s as r,sa as H,t as s,ta as I,u as t,ua as J,v as u,va as K,w as v,wa as L,x as w,xa as M,y as x,ya as N,z as y,za as O}from"./chunk-AIDBRYAC.js";import"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{f as BROWSER_DELIVERY_TTL_MS,n as DEFAULT_HUB_API_URL,o as HubNotConfiguredError,V as ManagedOAuthDeliveryError,g as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ca as attachManagedRefreshAuth,i as buildBrowserDeliveryRedirectUrl,l as buildClientBridgeBrowserDeliveryUrl,ea as createConnectSessionJti,ja as createConnectTokenJti,B as createHubConnectSession,E as createHubPermissionSession,da as createHubRouteHandlers,pa as createPermissionSessionJti,h as createSignedTokenJti,ia as decodeConnectSessionTokenFromPath,oa as decodeConnectTokenFromPath,sa as decodePermissionTokenFromPath,Q as deliverConnectCreateLink,U as deliverSignedEnvelope,S as describeDeliveryNetworkError,na as encodeConnectTokenForPath,O as extractConnectLinkFromDeliveryAck,H as extractProbeFromDeliveryAck,G as extractRunFromDeliveryAck,N as extractSyncFromDeliveryAck,F as formatHubApprovalMessage,a as formatProviderDisplayName,T as formatServerDeliveryError,fa as getConnectSessionExpiryMs,C as getConnectStatusForTenant,ka as getConnectTokenExpiryMs,q as getHubConfig,ba as getManagedAccessToken,X as handleHubDeliveryGet,Y as handleHubDeliveryPost,_ as handleHubDeliveryRequest,Z as hubDeliveryToResponse,s as inferHubEnvironmentSlug,b as isLoopbackUrl,M as isServerDeliveryAckSuccessful,D as listHubProjectConnections,p as normalizeHubConfig,P as parseConnectLinkFromDeliveryBody,t as parseConnectSessionResponse,x as parseConnectStatusResponse,y as parseHubApiErrorBody,w as parseOAuthRefreshResponse,v as parsePermissionSessionResponse,u as parseProjectConnectionsResponse,L as parseServerDeliveryAckBody,R as parseSyncFromDeliveryBody,m as prepareClientBridgeDeliveryTransport,W as processManagedOAuthDelivery,A as registerHubWebhookTenantLink,c as resolveDeliveryTransport,z as resolveHubDeliveryUrl,r as resolveHubOAuthCallbackUrl,$ as respondToHubDelivery,aa as respondToHubDeliveryFromRequest,j as signBrowserDeliveryToken,ga as signConnectSessionToken,la as signConnectToken,I as signDeliveryEnvelope,qa as signPermissionToken,d as usesBrowserDelivery,e as validateProductionDeliveryUrl,k as verifyBrowserDeliveryToken,ha as verifyConnectSessionToken,ma as verifyConnectToken,J as verifyDeliveryEnvelope,ra as verifyPermissionToken,K as verifySignedTunnelDelivery};
|