corsair 0.1.123 → 0.1.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-CWMYDY33.js → chunk-IXPIBTH2.js} +17 -17
- package/dist/{connect-JBFEIF2J.js → connect-K3DEFQJW.js} +1 -1
- package/dist/core.js +1 -1
- package/dist/hub.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{loop-UGODWXLA.js → loop-C3QS4HV3.js} +1 -1
- package/dist/oauth.js +1 -1
- package/dist/{setup-KEZWK5UF.js → setup-Y6N7P6MY.js} +1 -1
- package/dist/{setup-introspect-UOQO3JTV.js → setup-introspect-JISZAHLI.js} +1 -1
- package/dist/setup.js +1 -1
- package/dist/tunnel.js +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as we,b as Gt,c as zt}from"./chunk-4OLKWKJG.js";import{a as So,b as Ce,c as _o,d as v,e as W,f as Eo,g as G,h as L,i as I,j as Ln,k as Do,l as Oo,m as Zt,n as Mo,o as Ho}from"./chunk-VOH7OVWP.js";import{a as Io}from"./chunk-F2EV3CHK.js";import{ZodBoolean as al,ZodDate as ul,ZodEnum as cl,ZodNullable as ll,ZodNumber as dl,ZodObject as pl,ZodOptional as gl,ZodRecord as fl,ZodString as yl,ZodType as ml}from"zod";var $n=["dropboxsign","ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","asana","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boloforms","boltiot","bonsai","bookingmood","botpress","botsonic","bouncer","box","boxhero","brandfetch","brex","browseai","browserless","bugsnag","cal","calendly","canva","canvas","chatbotkit","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","contentfulgraphql","contextsevenmcp","crowterminal","cursor","customgpt","databricks","datadog","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dropbox","epicgames","exa","facebook","faraday","figma","firecrawl","fireflies","formbricks","gemini","github","gitlab","gmail","googleaddressvalidation","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","resend","retailed","salesforce","securitytrails","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","tisane","timecamp","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wiza","workday","xquik","youcom","youtube","zendesk","zohomail","zoom","zoominfo"],Bo={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",asana:"Asana",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beeminder:"Beeminder",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",brex:"Brex",browseai:"Browse AI",browserless:"Browserless",bugsnag:"BugSnag",cal:"Cal",calendly:"Calendly",canva:"Canva",canvas:"Canvas LMS",chatbotkit:"ChatBotKit",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",databricks:"Databricks",datadog:"Datadog",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",epicgames:"Epic Games",exa:"Exa",facebook:"Facebook",faraday:"Faraday",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",formbricks:"Formbricks",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",retailed:"Retailed",salesforce:"Salesforce",securitytrails:"SecurityTrails",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",tisane:"Tisane",timecamp:"TimeCamp",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wiza:"Wiza",workday:"Workday",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function ve(e){let n=Bo[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}function _(e){return typeof e=="string"&&e.length>0}function ga(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function fa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Wn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!_(n.connectUrl)||!_(n.token)||!_(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:_(n.environmentId)?n.environmentId:n.projectId};return _(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function jn(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(!_(r.tenantId)||!_(r.plugin)||!ga(r.status)||!fa(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:_(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!_(n.approvalUrl)||!_(n.token)||!_(n.projectId)||!_(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 qe(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(_(n.access_token))return{access_token:n.access_token,refresh_token:_(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:_(n.scope)?n.scope:void 0};throw new Error(_(n.error)?_(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function ya(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function ma(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;_(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 ha(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 Fo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!_(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(!_(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=ma(o.fields),a=ya(o.missingRequiredFields),u=ha(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:_(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function qn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function No(e){return e.replace(/\/$/,"")}function Jt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return we()}catch{return null}}function Uo(e){let n=Jt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Lo(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 $o(e,n,t){if(n===404&&t)return t;let r=qn(e);return r||`Hub API returned HTTP ${n}`}async function x(e){let n=No(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Uo(e.hub)},body:JSON.stringify(e.body)}),r=await Lo(t);if(!t.ok)throw new Error($o(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=No(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Uo(e.hub)}}),r=await Lo(t);if(!t.ok)throw new Error($o(r,t.status,e.notFoundMessage));return e.parseResponse(r)}function Zn(e){return e&&typeof e=="object"?e:{}}function Wo(e){let n=Zn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function Vt(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Zn(t);return{chat:r.thread,reply:Wo(r.reply)}}})}async function Yt(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:Wo})}async function Xt(e,n){return $({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Zn(t).threads;return Array.isArray(r)?r:[]}})}async function Qt(e,n){return $({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Zn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Pa}from"crypto";var ba="corsair:client-bridge";function er(e){return new URL(e).origin}function Ze(e){let n=JSON.stringify({type:ba,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(er(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
1
|
+
import{a as we,b as Zt,c as Gt}from"./chunk-4OLKWKJG.js";import{a as Io,b as Ce,c as So,d as v,e as W,f as _o,g as G,h as L,i as I,j as Ln,k as Eo,l as Do,m as qt,n as Oo,o as Mo}from"./chunk-VOH7OVWP.js";import{a as xo}from"./chunk-F2EV3CHK.js";import{ZodBoolean as sl,ZodDate as al,ZodEnum as ul,ZodNullable as cl,ZodNumber as ll,ZodObject as dl,ZodOptional as pl,ZodRecord as gl,ZodString as fl,ZodType as yl}from"zod";var $n=["dropboxsign","ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","asana","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boloforms","boltiot","bonsai","bookingmood","botpress","botsonic","bouncer","box","boxhero","brandfetch","brex","browseai","browserless","bugsnag","cal","calendly","canva","canvas","chatbotkit","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","contentfulgraphql","contextsevenmcp","crowterminal","cursor","customgpt","databricks","datadog","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dropbox","epicgames","exa","facebook","faraday","figma","firecrawl","fireflies","formbricks","gemini","github","gitlab","gmail","googleaddressvalidation","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","resend","retailed","salesforce","securitytrails","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","tisane","timecamp","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wiza","workday","xquik","youcom","youtube","zendesk","zohomail","zoom","zoominfo"],Ho={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",asana:"Asana",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beeminder:"Beeminder",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",brex:"Brex",browseai:"Browse AI",browserless:"Browserless",bugsnag:"BugSnag",cal:"Cal",calendly:"Calendly",canva:"Canva",canvas:"Canvas LMS",chatbotkit:"ChatBotKit",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",databricks:"Databricks",datadog:"Datadog",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",epicgames:"Epic Games",exa:"Exa",facebook:"Facebook",faraday:"Faraday",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",formbricks:"Formbricks",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",retailed:"Retailed",salesforce:"Salesforce",securitytrails:"SecurityTrails",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",tisane:"Tisane",timecamp:"TimeCamp",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wiza:"Wiza",workday:"Workday",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function ve(e){let n=Ho[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}function _(e){return typeof e=="string"&&e.length>0}function pa(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function ga(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Wn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!_(n.connectUrl)||!_(n.token)||!_(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:_(n.environmentId)?n.environmentId:n.projectId};return _(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function jn(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(!_(r.tenantId)||!_(r.plugin)||!pa(r.status)||!ga(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:_(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!_(n.approvalUrl)||!_(n.token)||!_(n.projectId)||!_(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 Ze(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(_(n.access_token))return{access_token:n.access_token,refresh_token:_(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:_(n.scope)?n.scope:void 0};throw new Error(_(n.error)?_(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function fa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function ya(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;_(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 ma(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 Bo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!_(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(!_(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=ya(o.fields),a=fa(o.missingRequiredFields),u=ma(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:_(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function qn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function Fo(e){return e.replace(/\/$/,"")}function zt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return we()}catch{return null}}function No(e){let n=zt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Uo(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 Lo(e,n,t){if(n===404&&t)return t;let r=qn(e);return r||`Hub API returned HTTP ${n}`}async function x(e){let n=Fo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...No(e.hub)},body:JSON.stringify(e.body)}),r=await Uo(t);if(!t.ok)throw new Error(Lo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=Fo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...No(e.hub)}}),r=await Uo(t);if(!t.ok)throw new Error(Lo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}function Zn(e){return e&&typeof e=="object"?e:{}}function $o(e){let n=Zn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function Jt(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Zn(t);return{chat:r.thread,reply:$o(r.reply)}}})}async function Vt(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:$o})}async function Yt(e,n){return $({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Zn(t).threads;return Array.isArray(r)?r:[]}})}async function Xt(e,n){return $({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Zn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ta}from"crypto";var ha="corsair:client-bridge";function Qt(e){return new URL(e).origin}function Ge(e){let n=JSON.stringify({type:ha,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(Qt(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
2
|
(function () {
|
|
3
3
|
var message = ${n};
|
|
4
4
|
var targetOrigin = ${t};
|
|
@@ -6,17 +6,17 @@ import{a as we,b as Gt,c as zt}from"./chunk-4OLKWKJG.js";import{a as So,b as Ce,
|
|
|
6
6
|
window.parent.postMessage(message, targetOrigin);
|
|
7
7
|
}
|
|
8
8
|
})();
|
|
9
|
-
</script></body></html>`}var ka=new Set(["localhost","127.0.0.1","[::1]","::1"]);function nr(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ka.has(n)}catch{return!1}}function bn(e){return e==="development"?"browser":"server"}function jo(e){return bn(e)==="browser"}function Ko(e){return nr(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ta}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as wa,randomBytes as Ca,timingSafeEqual as va}from"crypto";function le(){return Ca(16).toString("base64url")}function kn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return wa("sha256",t).update(e).digest("base64url")}function ie(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=kn(o,t);try{if(!va(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 Gn(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=kn(i,n);return`${i}.${s}`}function wn(e,n,t){let r=Math.floor(Date.now()/1e3);return Gn(e,n,r+Math.floor(t/1e3))}function He(e){return decodeURIComponent(e)}function tr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function qo(e){let n=e.trim();return n.length>0?n:null}function Ge(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function ze(e,n){if(!qo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ta(16).toString("base64url"),iat:t,exp:t+Math.floor(Te/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=kn(o,n);return`${o}.${i}`}function Pe(e,n){return qo(n)?ie(e,n):null}function Aa(e){let n=er(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 rr(e){let n=ze(Aa(e),e.signingSecret);return Ge(e.deliveryUrl,n)}function Zo(e){if(bn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Pa(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:rr(r)}}var Cn="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},vn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function or(e){let n=(e.apiUrl?.trim()||Cn).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new vn;return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function zn(e){return or(e)}function Ra(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Ra(n))throw new de;return n}function Go(e){return e.replace(/\/$/,"")}function Jn(e){return e.oauthCallbackUrl?Go(e.oauthCallbackUrl.trim()):`${Go(e.apiUrl)}/oauth/callback`}function Je(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as zo,createDecipheriv as Jo,randomBytes as Vn,scrypt as xa}from"crypto";import{promisify as Ia}from"util";var Vo=Ia(xa),Yn="aes-256-gcm",Yo=12,Xn=16,Sa=16,Be=32;function pe(){return Vn(Be).toString("base64")}async function ge(e,n){let t=Vn(Sa),r=await Vo(n,t,Be),o=Vn(Yo),i=zo(Yn,r,o,{authTagLength:Xn}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Vo(n,s,Be),d=Jo(Yn,c,a,{authTagLength:Xn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function ir(e,n){let t=Buffer.from(n,"base64"),r=Vn(Yo),o=zo(Yn,t,r,{authTagLength:Xn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function Tn(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=Jo(Yn,i,s,{authTagLength:Xn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function Ae(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=ir(o,n);return t}function fe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Tn(o,n);return t}function Pn(e,n,t){let r=fe(e,n);return Ae(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 sr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function N(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...L[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:sr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let k=await u.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await u.getIntegration(),b=await c(),C=k.config;return!C||Object.keys(C).length===0?{}:fe(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await c(),C;try{C=await d()}catch(E){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,E),C={}}let T={...C};for(let[E,M]of Object.entries(k))M===null?delete T[E]:T[E]=M;let D=Ae(T,b);await u.updateIntegration({config:D})};return{get_dek:c,issue_new_dek:async()=>{let k=await u.getIntegration(),b=pe(),C={};if(k.dek){let D=await Y(k.dek,r),E=k.config;E&&Object.keys(E).length>0&&(C=Pn(E,D,b))}let T=await ge(b,r);return await u.updateIntegration({config:C,dek:T}),l=b,b},...Xo(d,g,s)}}function H(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...L[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:A.id,config:sr(A.config),dek:A.dek??null},c}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:sr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},T=Promise.resolve(),D=w=>{let A=T.then(()=>E(w));return T=A.catch(()=>{}),A},E=async w=>{let A=await h(),R;try{R=await b()}catch(S){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,S),R={}}let z={...R};for(let[S,te]of Object.entries(w))te===null?delete z[S]:z[S]=te;let ce=Ae(z,A);await p.updateAccount({config:ce})},M={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=pe(),R={};if(w.dek){let ce=await Y(w.dek,o),S=w.config;S&&Object.keys(S).length>0&&(R=Pn(S,ce,A))}let z=await ge(A,o);return await p.updateAccount({config:R,dek:z}),g=A,A},...Xo(b,D,u)};return n==="oauth_2"&&(M.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),M}async function Qo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=pe(),i=await ge(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function ei(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=pe(),a=await ge(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var _a=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Re(e){return _a.has(e)}function Ea(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Da(e){return!Re(e)}function Oa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ma(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ha(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Oa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ni(e,n){if(!e)return!1;let t=G(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ba(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Fa(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Na(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:Ha(n,t),fields:t,missingRequiredFields:r}}async function Fe(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],u=N({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=H({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=Ba(n,r),d=Fa(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:Ea(r,g),configured:await ni(u,g)});for(let g of d)p.push({name:g,level:"account",required:Da(g),configured:await ni(l,g)});if(Ma(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Na(n.id,r,p)}async function An(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 Fe(e,s,r);a&&i.push(a)}return i}function Qn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ti=Symbol.for("corsair:internal"),ri=new WeakMap,oi=new WeakMap;function Ua(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function La(e){if(e.database){let t=ri.get(e.database);return t||(t=new Map,ri.set(e.database,t)),t}let n=oi.get(e);return n||(n=new Map,oi.set(e,n)),n}function $a(e){return e.multiTenancy?{withTenant:()=>({}),[ti]:e}:{[ti]:e}}async function Ve(e,n){if(!e.database)return;let t=n.trim()||"default",r=La(e),o=Ua(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-KEZWK5UF.js");await a($a(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Rn from"crypto";function xe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function ar(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 Ye(e,n){let t=Rn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var ur=600*1e3;function et(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Rn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Rn.timingSafeEqual(s,a)?null:ar(r,{maxAgeMs:ur})}function ii(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function si(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 Xe(e,n){await x({hub:e,path:"/connections/report",body:ii(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Wa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof de)return}}async function ja(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Fe(n,e.plugin,r);o&&ui(e.hub,si({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function ai(e,n){Wa(e,n)}function ui(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function xn(e){ja(e).catch(()=>{})}async function ye(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Fe(t,n.plugin,n.tenantId);o&&ai(e,si({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 nt(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 ci=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Ka(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 qa(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=ci(n.config),o={};Object.keys(r).length>0&&(o=fe(r,t)),o[e.link.linkType]=e.link.externalId;let i=Ae(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function Qe(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await Ka({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=H({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await qa({database:n,kek:t,accountId:u,link:i})}async function cr(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Y(a.dek,t),c=ci(a.config)[o];if(!c)continue;if(Tn(c,u)===i)return a}catch{continue}return null}async function tt(e){return(await cr(e))?.tenant_id??null}async function li(e){return tt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as di from"querystring";function Ne(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}?${di.stringify(i)}`}async function pi(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function en(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await pi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await ye(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var j=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function gi(e){let n=e.oauthConfig;if(!n)throw new j("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Za(e,n,t,r){let o=Ho(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=pe(),u=await ge(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function lr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=W(s,n,p=>new j("plugin_not_found",p)),u=gi(a),c=await N({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Ne({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=Ye(xe(n,r),s.kek);return{url:Ne({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function Ga(e,n){return{...n??{},...e}}async function In(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new j("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=et(r,i.kek);if(!h)throw new j("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new j("no_database","No database configured on corsair instance");let u=W(i,s,h=>new j("plugin_not_found",h)),l=gi(u),c=N({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new j("credentials_not_configured",`Credentials not configured for '${s}'`);await Za(i.database,s,a,i.kek);let g=await rt(t,d,p,l,o);if(!g.access_token)throw new j("no_access_token",`No access_token returned from ${l.providerName}`);let f=H({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await ye(e,{plugin:u,tenantId:a}).catch(()=>{});try{let h=Ga(g,n.callbackParams),k=await nt(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await Qe({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&Xe(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(u.subscribe)try{await en(e,u,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function za(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??en,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let u=t.plugins.find(c=>c.id===a.integrationName);if(!u?.subscribe)continue;let l=`${u.id}/${a.tenantId}`;try{let c=I(u)??"oauth_2",d=H({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function fi(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return za({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Ja(e,n={}){let t=!1,r=()=>{t||(t=!0,fi(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 yi(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await ot(e,{silent:!0})}async function nn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ve(t,n)}var Va=Symbol.for("corsair:internal"),Ya=new Set(["access_token","refresh_token","expires_at","scope"]);function Xa(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Qa(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Ya.has(t)):n.filter(t=>!Re(t))}function mi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function eu(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function nu(e){return{[Va]:mi(e)}}async function it(e,n,t={}){let r=Jn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=mi(e),a=nu(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=Xa(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Fe(s,u,n),g=Ln(u,l),f=Qa(l,g),h={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),c==="oauth"){let b=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await lr(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${u.id}`)}}o.push(h)}return o}async function Up(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return it({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function hi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ve(e.internalConfig??eu(e),n)}async function bi(e,n){await nn(e,n)}async function ki(e,n){let t=Je(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Wn})}async function dr(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await hi(t,n.tenantId);let r=await it(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 ki(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function st(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await bi(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 it(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 ki(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function at(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await tu(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 tu(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-UOQO3JTV.js"),{postHubConnectSession:i}=await import("./connect-JBFEIF2J.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function tn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var X=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function ru(e){let n=e.oauthConfig;if(!n)throw new X("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function pr(e,n){let t=v(e,()=>new X("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new X("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new X("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=et(n,t.kek);if(!o)throw new X("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=W(t,i,p=>new X("plugin_not_found",p)),u=ru(a),c=await N({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new X("client_id_not_configured",`client_id not configured for '${i}'`);let d=Ne({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as iu}from"async_hooks";import{randomBytes as su}from"crypto";import{v4 as au}from"uuid";async function ut(e,n){let t=Je(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Kn})}function ct(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var gr="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 yr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function wi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function fr(e){return ct(e)}async function mr(e,n){if(yr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?wi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await ut(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:ou(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ou(e){try{return JSON.parse(e)}catch{return e}}async function lt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await mr(e,n);return{...n,approvalUrl:r}}async function hr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await mr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return yr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):fr(g):gr:r?g?fr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:gr}var rn=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var vi=new iu,dt=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 br(e){return vi.run(!0,e)}function Ti(){return vi.getStore()===!0}function kr(e,n){if(Ti()&&n!=="read")throw new dt(e,n)}var uu={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 cu(e,n,t){return t!==void 0?t:uu[n][e]}function wr(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 Pi(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 Ci(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 Ai(e){let n=cu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
9
|
+
</script></body></html>`}var ba=new Set(["localhost","127.0.0.1","[::1]","::1"]);function er(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ba.has(n)}catch{return!1}}function bn(e){return e==="development"?"browser":"server"}function Wo(e){return bn(e)==="browser"}function jo(e){return er(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as va}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as ka,randomBytes as wa,timingSafeEqual as Ca}from"crypto";function le(){return wa(16).toString("base64url")}function kn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return ka("sha256",t).update(e).digest("base64url")}function ie(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=kn(o,t);try{if(!Ca(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 Gn(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=kn(i,n);return`${i}.${s}`}function wn(e,n,t){let r=Math.floor(Date.now()/1e3);return Gn(e,n,r+Math.floor(t/1e3))}function He(e){return decodeURIComponent(e)}function nr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Ko(e){let n=e.trim();return n.length>0?n:null}function ze(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Je(e,n){if(!Ko(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??va(16).toString("base64url"),iat:t,exp:t+Math.floor(Te/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=kn(o,n);return`${o}.${i}`}function Pe(e,n){return Ko(n)?ie(e,n):null}function Pa(e){let n=Qt(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 tr(e){let n=Je(Pa(e),e.signingSecret);return ze(e.deliveryUrl,n)}function qo(e){if(bn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ta(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:tr(r)}}var Cn="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},vn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function rr(e){let n=(e.apiUrl?.trim()||Cn).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new vn;return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function zn(e){return rr(e)}function Aa(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Aa(n))throw new de;return n}function Zo(e){return e.replace(/\/$/,"")}function Jn(e){return e.oauthCallbackUrl?Zo(e.oauthCallbackUrl.trim()):`${Zo(e.apiUrl)}/oauth/callback`}function Ve(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as Go,createDecipheriv as zo,randomBytes as Vn,scrypt as Ra}from"crypto";import{promisify as xa}from"util";var Jo=xa(Ra),Yn="aes-256-gcm",Vo=12,Xn=16,Ia=16,Be=32;function pe(){return Vn(Be).toString("base64")}async function ge(e,n){let t=Vn(Ia),r=await Jo(n,t,Be),o=Vn(Vo),i=Go(Yn,r,o,{authTagLength:Xn}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Jo(n,s,Be),d=zo(Yn,c,a,{authTagLength:Xn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function or(e,n){let t=Buffer.from(n,"base64"),r=Vn(Vo),o=Go(Yn,t,r,{authTagLength:Xn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function Tn(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=zo(Yn,i,s,{authTagLength:Xn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function Ae(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=or(o,n);return t}function fe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Tn(o,n);return t}function Pn(e,n,t){let r=fe(e,n);return Ae(r,t)}function Yo(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 ir=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function N(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...L[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:ir(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let k=await u.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await u.getIntegration(),b=await c(),C=k.config;return!C||Object.keys(C).length===0?{}:fe(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await c(),C;try{C=await d()}catch(E){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,E),C={}}let T={...C};for(let[E,M]of Object.entries(k))M===null?delete T[E]:T[E]=M;let D=Ae(T,b);await u.updateIntegration({config:D})};return{get_dek:c,issue_new_dek:async()=>{let k=await u.getIntegration(),b=pe(),C={};if(k.dek){let D=await Y(k.dek,r),E=k.config;E&&Object.keys(E).length>0&&(C=Pn(E,D,b))}let T=await ge(b,r);return await u.updateIntegration({config:C,dek:T}),l=b,b},...Yo(d,g,s)}}function H(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...L[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:A.id,config:ir(A.config),dek:A.dek??null},c}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:ir(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},T=Promise.resolve(),D=w=>{let A=T.then(()=>E(w));return T=A.catch(()=>{}),A},E=async w=>{let A=await h(),R;try{R=await b()}catch(S){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,S),R={}}let z={...R};for(let[S,te]of Object.entries(w))te===null?delete z[S]:z[S]=te;let ce=Ae(z,A);await p.updateAccount({config:ce})},M={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=pe(),R={};if(w.dek){let ce=await Y(w.dek,o),S=w.config;S&&Object.keys(S).length>0&&(R=Pn(S,ce,A))}let z=await ge(A,o);return await p.updateAccount({config:R,dek:z}),g=A,A},...Yo(b,D,u)};return n==="oauth_2"&&(M.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),M}async function Xo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=pe(),i=await ge(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Qo(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=pe(),a=await ge(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var Sa=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Re(e){return Sa.has(e)}function _a(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Ea(e){return!Re(e)}function Da(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Oa(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ma(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Da(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ei(e,n){if(!e)return!1;let t=G(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ha(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Ba(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Fa(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:Ma(n,t),fields:t,missingRequiredFields:r}}async function Fe(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],u=N({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=H({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=Ha(n,r),d=Ba(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:_a(r,g),configured:await ei(u,g)});for(let g of d)p.push({name:g,level:"account",required:Ea(g),configured:await ei(l,g)});if(Oa(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Fa(n.id,r,p)}async function An(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 Fe(e,s,r);a&&i.push(a)}return i}function Qn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ni=Symbol.for("corsair:internal"),ti=new WeakMap,ri=new WeakMap;function Na(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ua(e){if(e.database){let t=ti.get(e.database);return t||(t=new Map,ti.set(e.database,t)),t}let n=ri.get(e);return n||(n=new Map,ri.set(e,n)),n}function La(e){return e.multiTenancy?{withTenant:()=>({}),[ni]:e}:{[ni]:e}}async function Ye(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ua(e),o=Na(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-Y6N7P6MY.js");await a(La(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Rn from"crypto";function xe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function sr(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 Xe(e,n){let t=Rn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var ar=600*1e3;function et(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Rn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Rn.timingSafeEqual(s,a)?null:sr(r,{maxAgeMs:ar})}function oi(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function ii(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 Qe(e,n){await x({hub:e,path:"/connections/report",body:oi(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function $a(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof de)return}}async function Wa(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Fe(n,e.plugin,r);o&&ai(e.hub,ii({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function si(e,n){$a(e,n)}function ai(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function xn(e){Wa(e).catch(()=>{})}async function ye(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Fe(t,n.plugin,n.tenantId);o&&si(e,ii({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 nt(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 ui=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function ja(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 Ka(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=ui(n.config),o={};Object.keys(r).length>0&&(o=fe(r,t)),o[e.link.linkType]=e.link.externalId;let i=Ae(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function en(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await ja({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=H({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await Ka({database:n,kek:t,accountId:u,link:i})}async function ur(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Y(a.dek,t),c=ui(a.config)[o];if(!c)continue;if(Tn(c,u)===i)return a}catch{continue}return null}async function tt(e){return(await ur(e))?.tenant_id??null}async function ci(e){return tt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as li from"querystring";function Ne(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}?${li.stringify(i)}`}async function di(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=F(e),i=await di(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await ye(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var j=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function pi(e){let n=e.oauthConfig;if(!n)throw new j("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function qa(e,n,t,r){let o=Mo(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=pe(),u=await ge(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function cr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=W(s,n,p=>new j("plugin_not_found",p)),u=pi(a),c=await N({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Ne({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=Xe(xe(n,r),s.kek);return{url:Ne({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function Za(e,n){return{...n??{},...e}}async function In(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new j("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=et(r,i.kek);if(!h)throw new j("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new j("no_database","No database configured on corsair instance");let u=W(i,s,h=>new j("plugin_not_found",h)),l=pi(u),c=N({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new j("credentials_not_configured",`Credentials not configured for '${s}'`);await qa(i.database,s,a,i.kek);let g=await rt(t,d,p,l,o);if(!g.access_token)throw new j("no_access_token",`No access_token returned from ${l.providerName}`);let f=H({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await ye(e,{plugin:u,tenantId:a}).catch(()=>{});try{let h=Za(g,n.callbackParams),k=await nt(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await en({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&Qe(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(u.subscribe)try{await nn(e,u,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function Ga(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=I(u)??"oauth_2",d=H({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function gi(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return Ga({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function za(e,n={}){let t=!1,r=()=>{t||(t=!0,gi(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 fi(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await ot(e,{silent:!0})}async function tn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ye(t,n)}var Ja=Symbol.for("corsair:internal"),Va=new Set(["access_token","refresh_token","expires_at","scope"]);function Ya(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Xa(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Va.has(t)):n.filter(t=>!Re(t))}function yi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Qa(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function eu(e){return{[Ja]:yi(e)}}async function it(e,n,t={}){let r=Jn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=yi(e),a=eu(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=Ya(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Fe(s,u,n),g=Ln(u,l),f=Xa(l,g),h={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),c==="oauth"){let b=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await cr(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${u.id}`)}}o.push(h)}return o}async function Np(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return it({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function mi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ye(e.internalConfig??Qa(e),n)}async function hi(e,n){await tn(e,n)}async function bi(e,n){let t=Ve(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Wn})}async function lr(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await mi(t,n.tenantId);let r=await it(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 bi(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function st(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await hi(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 it(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 bi(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function at(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await nu(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 nu(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-JISZAHLI.js"),{postHubConnectSession:i}=await import("./connect-K3DEFQJW.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function rn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var X=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function tu(e){let n=e.oauthConfig;if(!n)throw new X("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function dr(e,n){let t=v(e,()=>new X("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new X("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new X("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=et(n,t.kek);if(!o)throw new X("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=W(t,i,p=>new X("plugin_not_found",p)),u=tu(a),c=await N({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new X("client_id_not_configured",`client_id not configured for '${i}'`);let d=Ne({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as ou}from"async_hooks";import{randomBytes as iu}from"crypto";import{v4 as su}from"uuid";async function ut(e,n){let t=Ve(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Kn})}function ct(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var pr="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 fr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function ki(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function gr(e){return ct(e)}async function yr(e,n){if(fr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?ki(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await ut(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:ru(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ru(e){try{return JSON.parse(e)}catch{return e}}async function lt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await yr(e,n);return{...n,approvalUrl:r}}async function mr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await yr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return fr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):gr(g):pr:r?g?gr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:pr}var on=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Ci=new ou,dt=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 hr(e){return Ci.run(!0,e)}function vi(){return Ci.getStore()===!0}function br(e,n){if(vi()&&n!=="read")throw new dt(e,n)}var au={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 uu(e,n,t){return t!==void 0?t:au[n][e]}function kr(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 Ti(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 wi(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 Pi(e){let n=uu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
10
|
Action: ${r}`,`
|
|
11
11
|
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
12
|
Action: ${r}`,`
|
|
13
13
|
Permission ID: ${a.id}`,`
|
|
14
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?wi(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=su(),l=iu(32).toString("hex"),c=e.timeoutMs??600*1e3,d=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:d}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
15
15
|
Action: ${r}`,`
|
|
16
16
|
Permission ID: ${u}`,`
|
|
17
17
|
Permission token: ${l}`,`
|
|
18
18
|
Expires at: ${d}`,`
|
|
19
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ci(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:d}}var P=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 O(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function se(e){let n={error:e.code,message:e.message,...e.extra};return O(e.status,n)}function Ie(e){return new P(404,"not_found",e)}function me(e,n={}){return new P(400,"bad_request",e,n)}function Ri(e,n){return W(e,n,t=>Ie(t))}async function xi(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=N({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=L[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 Ii(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await xi(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 pt(){return{ok:!0}}async function on(e){return Promise.all(e.plugins.map(n=>Ii(n,e)))}async function gt(e,n){let t=Ri(e,n);return Ii(t,e)}async function lu(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 Si(e,n){let t=await lu(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function sn(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 ft(e,n){if(!n)throw me("Tenant id must be a non-empty string");return Si(e,n)}async function yt(e,n){let t=n?.id?.trim();if(!t)throw me("Tenant id is required",{missingFields:["id"]});return Si(e,t)}async function mt(e,n){let t=n?.trim()||"default",r={},o=await An(e,t);for(let i of o)r[i.plugin]=Qn(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 Cr(e,n){if(!e.database)throw Ie(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Ie(`Permission '${n}' not found`);return lt(e,t)}function du(e){if(!e.oauthConfig)throw me(`Plugin '${e.id}' has no oauthConfig`)}function pu(e){if(!e.manual)throw new P(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function vr(e){let n=pu(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new P(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 gu(e){let n=!!e.hub,t=tn(e.manual);if(!n&&!t)throw new P(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function _i(e){if(!e.database||!e.kek)throw new P(500,"database_not_configured","A database and kek are required to issue connect links.")}async function fu(e,n){let t=n?.plugin?.trim();if(!t)throw me("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Ri(e,t);du(o);let i=vr(e);_i(e);let s=await xi(o,e);if(!s.configured)throw new P(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=Ye(xe(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new P(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()+ur).toISOString()}}async function yu(e,n,t){_i(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 st(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function ht(e,n,t){return gu(n),n.hub?yu(e,n,t):fu(n,t)}async function bt(e,n,t){if(n.hub&&!tn(n.manual))throw new P(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw me("state is required",{missingFields:["state"]});vr(n);try{return await pr(e,r)}catch(o){if(o instanceof X)switch(o.code){case"invalid_state":throw me("Invalid or expired state");case"client_id_not_configured":throw new P(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new P(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function kt(e,n,t){if(n.hub&&!tn(n.manual))throw new P(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 me("Missing required fields",{missingFields:i});let s=vr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw me("Invalid or expired state");case"credentials_not_configured":throw new P(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new P(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Tr(e,n){if(!e.database)throw Ie("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Ie("Permission not found");return lt(e,t)}async function Ei(e,n){return"id"in n?Cr(e,n.id):Tr(e,n.token)}import{createCipheriv as vu,createDecipheriv as Kg,randomBytes as Hi,scryptSync as Tu}from"crypto";import{createHmac as Pr,randomUUID as mu,timingSafeEqual as Oi}from"crypto";function Ar(e){return e.run??null}function Rr(e){return e.probe??null}function Mi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function wt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Pr("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":mu()}}}function xr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Mi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Me)return!1;let i=Pr("sha256",n).update(e.body).digest("hex");try{return Oi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function an(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Mi(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)>Me)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Pr("sha256",n).update(e.body).digest("hex");try{if(!Oi(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 un(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function Ct(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function vt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Sn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Ir(e){return Sn(un(e))}async function Sr(e){let n=await At({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=un(n.body),r=Ct({httpOk:n.ok,status:n.status,body:t}),o=Sn(t);if(!r||!o)throw new Error(Pt({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function Tt(e){return vt(un(e))}function hu(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 Di(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var bu="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",ku="Check the delivery URL configured for this environment.";function wu(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})`}. ${bu}`}function Cu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${ku}`}function _n(e,n){let t=hu(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 Pt(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:_n(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return wu(e);if(e.status===404)return Cu(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}): ${Di(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Di(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function At(e){let{body:n,headers:t}=wt(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:_n(e.deliveryUrl,r)}}}var Pu="aes-256-gcm",Au=12,Ru=16,xu=16,Iu=32;function Su(e,n){return Tu(e.trim(),n,Iu)}function _r(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Hi(xu),o=Su(t,r),i=Hi(Au),s=vu(Pu,o,i,{authTagLength:Ru}),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 _u=["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 Er(e){if(e instanceof So)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!_u.some(t=>n.includes(t))}function Eu(e){if(!e)return[];let n=I(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Re(r)):[]}async function En(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await ot(e,{silent:!0});let[r,o]=await Promise.all([sn(t),on(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=Eu(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 _r(i,n)}var ae=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Rt(e,n){let t=v(e,()=>new ae("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ae("no_database","Database not configured");let r=W(t,n.plugin,c=>new ae("plugin_not_found",c)),o=I(r);if(!o)throw new ae("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ae("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await nn(e,n.tenantId);let i=new Set(Ln(r,o)),a=r.authConfig?.[o]?.account??[],u=H({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ae("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ae("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ae("invalid_credentials","Provide at least one credential field to save");return await ye(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var ue=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Dr(e,n){let t=v(e,()=>new ue("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ue("no_database","Database not configured");let r=W(t,n.plugin,c=>new ue("plugin_not_found",c)),o=I(r);if(!o)throw new ue("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await yi(e);let i=new Set(Do(r,o)),a=r.authConfig?.[o]?.integration??[],u=N({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ue("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ue("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ue("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var xt=new Map;function Du(e){for(let[n,t]of xt)t<=e&&xt.delete(n)}function It(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();Du(r);let o=xt.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(xt.set(t,r+n),{ok:!0})}var Se=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function cn(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a,authType:u="managed",providerData:l}=n;if(!o.trim())throw new Se("no_access_token","Managed OAuth delivery missing access_token");let c=v(e,()=>new Se("invalid_corsair_instance","Invalid corsair instance"));if(!c.database)throw new Se("no_database","No database configured on corsair instance");let d=W(c,t,g=>new Se("plugin_not_found",g));await nn(e,r);let p=H({authType:u,integrationName:t,tenantId:r,kek:c.kek,database:c.database});await p.set_access_token(o),i&&await p.set_refresh_token(i),s&&await p.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await p.set_scope(a),await ye(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await nt(c.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[u]?.account??[];await Qe({database:c.database,kek:c.kek,pluginId:t,tenantId:r,link:g,authType:u,extraAccountFields:f})}catch(f){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,f)}c.hub&&Xe(c.hub,{plugin:t,tenantId:r,link:g,authType:u})}}catch(g){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,g)}return await en(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function Ou(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Bi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Ou(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=Bi(o,n,[...t,r]);if(i)return i}return null}function Mu(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Hu(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 Fi(e,n,t,r,o){let i=Mu(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Hu(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:$n;for(let g of p){let f=c[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let h=Bi(f.webhooks,u);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let C=await h.webhook.handler(b),T=!!Object.keys(C.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:T?{...C?.returnToSender,success:!0}:{success:!0},...C.responseHeaders&&{responseHeaders:C.responseHeaders}}}catch(C){return console.error(`Error executing webhook handler for ${g}.${k}:`,C),{plugin:g,action:k,body:s,response:{success:!1,error:C instanceof Error?C.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Bu}from"crypto";import*as Ue from"vm";var Ni="__corsairFailedStep",Fu=3e4,Or=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ui(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Li(e,n){return`st_${Bu("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function St(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 $i=new Set(["constructor","prototype","__proto__"]);function he(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Uu(e,n):t==="object"?Nu(e):e}function Nu(e){return new Proxy(e,{get(n,t){if(!$i.has(t))return he(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Uu(e,n){return new Proxy(e,{apply:(t,r,o)=>Lu(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!$i.has(r))return he(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Lu(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>he(n,void 0),n=>{throw he(n,void 0)}):he(e,void 0)}function $u(e){let n=Object.create(null),t=Ue.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ue.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ue.runInContext(`(function (hostRun, hostSleep) {
|
|
19
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?wi(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:d}}var P=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 O(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function se(e){let n={error:e.code,message:e.message,...e.extra};return O(e.status,n)}function Ie(e){return new P(404,"not_found",e)}function me(e,n={}){return new P(400,"bad_request",e,n)}function Ai(e,n){return W(e,n,t=>Ie(t))}async function Ri(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=N({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=L[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 xi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Ri(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 pt(){return{ok:!0}}async function sn(e){return Promise.all(e.plugins.map(n=>xi(n,e)))}async function gt(e,n){let t=Ai(e,n);return xi(t,e)}async function cu(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 Ii(e,n){let t=await cu(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function an(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 ft(e,n){if(!n)throw me("Tenant id must be a non-empty string");return Ii(e,n)}async function yt(e,n){let t=n?.id?.trim();if(!t)throw me("Tenant id is required",{missingFields:["id"]});return Ii(e,t)}async function mt(e,n){let t=n?.trim()||"default",r={},o=await An(e,t);for(let i of o)r[i.plugin]=Qn(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 wr(e,n){if(!e.database)throw Ie(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Ie(`Permission '${n}' not found`);return lt(e,t)}function lu(e){if(!e.oauthConfig)throw me(`Plugin '${e.id}' has no oauthConfig`)}function du(e){if(!e.manual)throw new P(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Cr(e){let n=du(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new P(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 pu(e){let n=!!e.hub,t=rn(e.manual);if(!n&&!t)throw new P(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function Si(e){if(!e.database||!e.kek)throw new P(500,"database_not_configured","A database and kek are required to issue connect links.")}async function gu(e,n){let t=n?.plugin?.trim();if(!t)throw me("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Ai(e,t);lu(o);let i=Cr(e);Si(e);let s=await Ri(o,e);if(!s.configured)throw new P(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=Xe(xe(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new P(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()+ar).toISOString()}}async function fu(e,n,t){Si(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 st(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function ht(e,n,t){return pu(n),n.hub?fu(e,n,t):gu(n,t)}async function bt(e,n,t){if(n.hub&&!rn(n.manual))throw new P(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw me("state is required",{missingFields:["state"]});Cr(n);try{return await dr(e,r)}catch(o){if(o instanceof X)switch(o.code){case"invalid_state":throw me("Invalid or expired state");case"client_id_not_configured":throw new P(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new P(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function kt(e,n,t){if(n.hub&&!rn(n.manual))throw new P(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 me("Missing required fields",{missingFields:i});let s=Cr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw me("Invalid or expired state");case"credentials_not_configured":throw new P(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new P(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function vr(e,n){if(!e.database)throw Ie("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Ie("Permission not found");return lt(e,t)}async function _i(e,n){return"id"in n?wr(e,n.id):vr(e,n.token)}import{createCipheriv as Cu,createDecipheriv as jg,randomBytes as Mi,scryptSync as vu}from"crypto";import{createHmac as Tr,randomUUID as yu,timingSafeEqual as Di}from"crypto";function Pr(e){return e.run??null}function Ar(e){return e.probe??null}function Oi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function wt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Tr("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":yu()}}}function Rr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Oi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Me)return!1;let i=Tr("sha256",n).update(e.body).digest("hex");try{return Di(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function un(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Oi(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)>Me)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Tr("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 cn(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function Ct(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function vt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Sn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function xr(e){return Sn(cn(e))}async function Ir(e){let n=await At({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=cn(n.body),r=Ct({httpOk:n.ok,status:n.status,body:t}),o=Sn(t);if(!r||!o)throw new Error(Pt({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function Tt(e){return vt(cn(e))}function mu(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 Ei(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var hu="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",bu="Check the delivery URL configured for this environment.";function ku(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})`}. ${hu}`}function wu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${bu}`}function _n(e,n){let t=mu(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 Pt(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:_n(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return ku(e);if(e.status===404)return wu(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}): ${Ei(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Ei(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function At(e){let{body:n,headers:t}=wt(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:_n(e.deliveryUrl,r)}}}var Tu="aes-256-gcm",Pu=12,Au=16,Ru=16,xu=32;function Iu(e,n){return vu(e.trim(),n,xu)}function Sr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Mi(Ru),o=Iu(t,r),i=Mi(Pu),s=Cu(Tu,o,i,{authTagLength:Au}),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 Su=["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 _r(e){if(e instanceof Io)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!Su.some(t=>n.includes(t))}function _u(e){if(!e)return[];let n=I(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Re(r)):[]}async function En(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await ot(e,{silent:!0});let[r,o]=await Promise.all([an(t),sn(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=_u(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 Sr(i,n)}var ae=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Rt(e,n){let t=v(e,()=>new ae("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ae("no_database","Database not configured");let r=W(t,n.plugin,c=>new ae("plugin_not_found",c)),o=I(r);if(!o)throw new ae("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ae("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await tn(e,n.tenantId);let i=new Set(Ln(r,o)),a=r.authConfig?.[o]?.account??[],u=H({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ae("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ae("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ae("invalid_credentials","Provide at least one credential field to save");return await ye(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var ue=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Er(e,n){let t=v(e,()=>new ue("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ue("no_database","Database not configured");let r=W(t,n.plugin,c=>new ue("plugin_not_found",c)),o=I(r);if(!o)throw new ue("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await fi(e);let i=new Set(Eo(r,o)),a=r.authConfig?.[o]?.integration??[],u=N({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ue("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ue("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ue("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var xt=new Map;function Eu(e){for(let[n,t]of xt)t<=e&&xt.delete(n)}function It(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();Eu(r);let o=xt.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(xt.set(t,r+n),{ok:!0})}var Se=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function ln(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a,authType:u="managed",providerData:l}=n;if(!o.trim())throw new Se("no_access_token","Managed OAuth delivery missing access_token");let c=v(e,()=>new Se("invalid_corsair_instance","Invalid corsair instance"));if(!c.database)throw new Se("no_database","No database configured on corsair instance");let d=W(c,t,g=>new Se("plugin_not_found",g));await tn(e,r);let p=H({authType:u,integrationName:t,tenantId:r,kek:c.kek,database:c.database});await p.set_access_token(o),i&&await p.set_refresh_token(i),s&&await p.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await p.set_scope(a),await ye(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await nt(c.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[u]?.account??[];await en({database:c.database,kek:c.kek,pluginId:t,tenantId:r,link:g,authType:u,extraAccountFields:f})}catch(f){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,f)}c.hub&&Qe(c.hub,{plugin:t,tenantId:r,link:g,authType:u})}}catch(g){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,g)}return await nn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function Du(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Hi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Du(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=Hi(o,n,[...t,r]);if(i)return i}return null}function Ou(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Mu(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 Bi(e,n,t,r,o){let i=Ou(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Mu(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:$n;for(let g of p){let f=c[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let h=Hi(f.webhooks,u);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let C=await h.webhook.handler(b),T=!!Object.keys(C.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:T?{...C?.returnToSender,success:!0}:{success:!0},...C.responseHeaders&&{responseHeaders:C.responseHeaders}}}catch(C){return console.error(`Error executing webhook handler for ${g}.${k}:`,C),{plugin:g,action:k,body:s,response:{success:!1,error:C instanceof Error?C.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Hu}from"crypto";import*as Ue from"vm";var Fi="__corsairFailedStep",Bu=3e4,Dr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ni(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Ui(e,n){return`st_${Hu("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function St(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 Li=new Set(["constructor","prototype","__proto__"]);function he(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Nu(e,n):t==="object"?Fu(e):e}function Fu(e){return new Proxy(e,{get(n,t){if(!Li.has(t))return he(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Nu(e,n){return new Proxy(e,{apply:(t,r,o)=>Uu(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!Li.has(r))return he(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Uu(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>he(n,void 0),n=>{throw he(n,void 0)}):he(e,void 0)}function Lu(e){let n=Object.create(null),t=Ue.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ue.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ue.runInContext(`(function (hostRun, hostSleep) {
|
|
20
20
|
const step = function step(name, fn) { return hostRun(name, fn); };
|
|
21
21
|
step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
|
|
22
22
|
return step;
|
|
@@ -39,28 +39,28 @@ ${e.code}
|
|
|
39
39
|
throw new Error('Workflow code must export a \`main\` function');
|
|
40
40
|
}
|
|
41
41
|
return main(__corsair, __payload, __step);
|
|
42
|
-
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let c,d=new Promise((p,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(c))}async function
|
|
42
|
+
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let c,d=new Promise((p,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(c))}async function Or(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=Ui(s,u);if(Object.hasOwn(n,l))return he(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(Ni(c))throw c;let d=St(c);t.push({stepId:l,name:s,seq:u,status:"failed",error:d});let p=new Error(d);throw p[Fi]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=Ui(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 Dr(Date.now()+c,s),o};try{await Lu({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Bu});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Ni(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=St(s),u=s!==null&&typeof s=="object"?s[Fi]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as _t from"vm";var $i=1e4;async function Mr(e){let n=Object.create(null),t=_t.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=he(e.corsair,void 0);let r=Wu(e.timeoutMs),o=`(async () => {
|
|
43
43
|
const __result = await (async () => {
|
|
44
44
|
${e.code}
|
|
45
45
|
})();
|
|
46
46
|
return JSON.stringify(__result) ?? 'null';
|
|
47
|
-
})()`;try{let i=await br(()=>{let s=_t.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:Wu(i)}}catch(i){return{status:"error",error:St(i)}}}function Wu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function ju(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?Wi:Math.min(e,Wi)}function Le(e){return e.deliveryMode==="auth.credentials"}function Dn(e){return e.deliveryMode==="connections.sync"}function Et(e){return e.deliveryMode==="connect.create_link"}function On(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Mn(e){return e.deliveryMode==="oauth.tokens"}function Dt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!Le(e)&&!Dn(e)&&!Et(e)&&!On(e)&&!Mn(e)}function Ku(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 qu(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await En(e,n)}}}}}catch(t){return{status:"failed",retryable:Er(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Zu(e,n){try{let t=await at(e,n);return Ku(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Br(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 Gu(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 tt({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function zu(e,n,t,r){let o=await Gu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await Fi(e,t.headers,t.body,i,{plugin:t.plugin,hubVerified:r&&t.hubVerified===!0});if(!s.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(s.response&&s.response.success===!1)return{status:"failed",retryable:!1,error:typeof s.response.error=="string"?s.response.error:"Webhook handler failed"};let a=s.response?.returnToSender,u=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(s.response?.data??s.response);return{status:"ok",webhookResponse:{status:s.response?.statusCode??200,body:u,headers:s.responseHeaders}}}async function Ju(e,n){return await In(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function Vu(e,n){return await cn(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope,authType:n.authType,providerData:n.providerData}),{status:"ok"}}async function Nr(e,n,t){let r=await Fr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Fr(e,n,t){let r=v(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 Yu(e,n){try{return await Rt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function Xu(e,n){try{return await Dr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function ji(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Qu(e,n){try{let t=ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Mr({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 ec(e,n){try{let t=ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Hr({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 Hn(e,n,t={}){let r=v(e),o=Br(n.headers,"x-corsair-signature"),i=Br(n.headers,"x-corsair-timestamp"),s=Br(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=an({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!l.ok)return{status:"failed",retryable:!1,error:l.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let c=It(`nonce:${s.trim()}`,Me);if(!c.ok)return{status:"failed",retryable:!1,error:c.error};a=!0}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let u;try{u=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(u.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(u.type){case"webhook":return zu(e,r,u.payload,a);case"oauth.callback":return Ju(e,u.payload);case"oauth.tokens":return Vu(e,u.payload);case"permission.approve":return Fr(e,u.payload,"approved");case"permission.deny":return Fr(e,u.payload,"denied");case"auth.credentials":return Yu(e,u.payload);case"integration.credentials":return Xu(e,u.payload);case"connect.create_link":return Zu(e,u.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?qu(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Qu(e,u.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?ec(e,u.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(u.type)}`}}}function nc(e){let n=e.webhookResponse;return e.status==="ok"?{status:n?.status??200,body:n?.body??{status:"ok"}}:{status:n?.status??502,body:n?.body??{status:"error",error:e.error??"delivery failed"}}}var Ur=3,tc=250;function rc(e){return e?.name==="AbortError"}async function oc(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function ic(e,n,t,r,o){for(let i=1;i<=Ur;i++){try{let s=await n.fetch(`${e.apiUrl}/api/dev/ack`,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(r),signal:o});if(s.ok)return await oc(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(rc(s))throw s}i<Ur&&await qi(tc)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Ur} attempts; the run may be retried`),!1}async function sc(e,n,t,r){let o={authorization:`Bearer ${n.projectApiKey}`},i=await t.fetch(`${n.apiUrl}/api/dev/pull`,{headers:o,signal:r});if(i.status===204)return"idle";if(!i.ok)return"error";let{deliveryId:s,body:a,headers:u}=await i.json(),l=await t.process(e,{headers:u,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:c,body:d}=nc(l);return await ic(n,t,o,{deliveryId:s,status:c,body:d},r)?"handled":"error"}var Ki=1e3,ac=5e3,uc=3e4;function qi(e){return new Promise(n=>setTimeout(n,e))}var Ot=globalThis.__corsairConnectLoops??=new Map;function cc(e,n={fetch,process:Hn}){let t;try{t=F(e)}catch{return{stop:()=>{}}}if(!t.projectApiKey.startsWith("ck_dev_"))return{stop:()=>{}};if(!t.allowWorkflowExecution)return console.warn("[corsair] workflow executions not enabled. Please set hub: { ..., allowWorkflowExecution: true }"),{stop:()=>{}};let r=t.projectApiKey;if(Ot.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Ot.set(r,o);let i=()=>{Ot.get(r)===o&&Ot.delete(r)},s=!1,a=null;return(async()=>{let l=Ki,c=!1,d=async p=>{c||(console.warn("[corsair] connect loop error; retrying",p),c=!0),s||await qi(l),l=Math.min(l*2,ac)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),uc);try{await sc(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(c=!1,l=Ki)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function Zi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Gi(e,n,t={}){let r=v(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await An(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>lc(l,i)).map(l=>{let c=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:ve(l.id),authKind:Zi(c),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:ve(l.id),authKind:Zi(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function zi(e,n){let t=F(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:jn})}var Ji=1024*1024,Vi=3e4;function $e(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:Ji}function We(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:Vi}function ln(e){return new P(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function dc(e){return new P(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Mt(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(dc(n)),n)})])}finally{clearTimeout(t)}}async function Ht(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:u}=await Mt(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=u.byteLength,o>n.maxBodyBytes)throw ln(n.maxBodyBytes);r.push(u)}let i=new Uint8Array(o),s=0;for(let a of r)i.set(a,s),s+=a.byteLength;return new TextDecoder().decode(i)}catch(r){throw t.cancel().catch(()=>{}),r}}var Lr=new Map;function Yi(e){let n;try{n=F(e)}catch{return}let t=Jt(n);t&&Lr.get(n.projectApiKey)!==t&&(Lr.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Lr.delete(n.projectApiKey)}))}var pc=[".corsair.dev"];function gc(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function fc(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:gc(n)?!0:pc.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Xi(e){return!e||!fc(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 Qi(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 $r(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 Wr(e,n){let t=F(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=Pe(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=It(`browser:${i.jti}`,Te);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Dn(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 En(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Et(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 at(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:u.connectUrl,expiresAt:u.expiresAt}})}}if(Le(i))return i.hubSuccessUrl?i.credentials?(await Rt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:$r(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:$r(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(On(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Nr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Mn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await cn(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope,authType:i.authType,providerData:i.providerData})}else{if(!Dt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await In(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 Dn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Et(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Le(i)&&i.hubSuccessUrl?{type:"redirect",url:$r(i.hubSuccessUrl,{error:u})}:Le(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({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 jr(e,n){let t=F(e),r=await Hn(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 Kr(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 qr(e,n){return n.method==="GET"?Wr(e,n.url):jr(e,{headers:n.headers,body:n.body??""})}async function Zr(e,n){try{let t=await qr(e,n);return Kr(t)}catch(t){if(t instanceof de)return Response.json({error:t.message},{status:503});throw t}}async function je(e,n,t){Yi(e);let r=n.method.toUpperCase(),o=Xi(n.headers.get("origin"));if(r==="OPTIONS")return o?new Response(null,{status:204,headers:o}):Response.json({error:"Method not allowed"},{status:405});if(r!=="GET"&&r!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await Zr(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Ht(n,{maxBodyBytes:$e(t?.maxBodyBytes),bodyStallTimeoutMs:We(t?.bodyStallTimeoutMs)}):void 0});return Qi(i,o)}var B=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}};function dn(e){if(e.forceRefresh||!e.accessToken||!e.expiresAt)return!1;let n=e.now??Math.floor(Date.now()/1e3);return Number(e.expiresAt)>n+300}async function pn(e,n,t){let r=Math.floor(Date.now()/1e3),o=t?Number(t):Number.NaN,i=typeof n.expires_in=="number"?r+n.expires_in:Number.isFinite(o)&&o>r?o:r+3600;return await e.set_access_token(n.access_token),await e.set_expires_at(String(i)),n.refresh_token&&await e.set_refresh_token(n.refresh_token),n.scope&&await e.set_scope(n.scope),i}var es=new WeakMap;function Bn(e,n,t){let r=es.get(e);r||(r=new Map,es.set(e,r));let o=r.get(n);if(o!==void 0)return o;let i=t().finally(()=>{r.delete(n)});return r.set(n,i),i}var ns=300;async function Gr(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Bn(t,a,async()=>{let[u,l,c]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!u&&!c)throw new B(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&u&&l&&Number(l)>d+ns)return{accessToken:u,expiresAt:Number(l),refreshed:!1};if(!c&&u&&!s){let f=l?Number(l):null;if(f===null||f>d+ns)return{accessToken:u,expiresAt:f??d+3600,refreshed:!1}}if(!c)throw new B(o,"managed");let p=await mc(r,o,i,c),g=await pn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function yc(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function mc(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:qe})}catch(o){let i=o instanceof Error?o.message:"";throw yc(i)?new B(n,"managed"):o}}async function ts(e,n){e._refreshAuth=async()=>(await Gr(n,{forceRefresh:!0})).accessToken}function rs(e){return{delivery:n=>je(e,n),deliveryOptions:n=>je(e,n)}}var os=1200*1e3;function zr(){return le()}function Jr(){return os}function Vr(e,n){return wn(e,n,os)}function Yr(e,n){return ie(e,n)}function Xr(e){return He(e)}var is=600*1e3;function Qr(){return le()}function eo(){return is}function no(e,n){return wn(e,n,is)}function to(e,n){return ie(e,n)}function ro(e){return tr(e)}function oo(e){return He(e)}function io(){return le()}function so(e,n,t){return Gn(e,n,Math.floor(t.getTime()/1e3))}function ao(e,n){return ie(e,n)}function uo(e){return He(e)}var gn=class extends Error{constructor(){super(`Corsair KEK is missing. Pass \`kek\` to createCorsair() or set CORSAIR_KEK in your environment. Generate one with: openssl rand -base64 ${Be}`),this.name="CorsairKekMissingError"}};function Bt(e,n){if(!n)return e??"";if(e===void 0||e==="")throw new gn;return e}function Ft(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.
|
|
47
|
+
})()`;try{let i=await hr(()=>{let s=_t.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:$u(i)}}catch(i){return{status:"error",error:St(i)}}}function $u(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function Wu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?$i:Math.min(e,$i)}function Le(e){return e.deliveryMode==="auth.credentials"}function Dn(e){return e.deliveryMode==="connections.sync"}function Et(e){return e.deliveryMode==="connect.create_link"}function On(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Mn(e){return e.deliveryMode==="oauth.tokens"}function Dt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!Le(e)&&!Dn(e)&&!Et(e)&&!On(e)&&!Mn(e)}function ju(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 Ku(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await En(e,n)}}}}}catch(t){return{status:"failed",retryable:_r(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function qu(e,n){try{let t=await at(e,n);return ju(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Hr(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 Zu(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 tt({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function Gu(e,n,t,r){let o=await Zu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await Bi(e,t.headers,t.body,i,{plugin:t.plugin,hubVerified:r&&t.hubVerified===!0});if(!s.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(s.response&&s.response.success===!1)return{status:"failed",retryable:!1,error:typeof s.response.error=="string"?s.response.error:"Webhook handler failed"};let a=s.response?.returnToSender,u=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(s.response?.data??s.response);return{status:"ok",webhookResponse:{status:s.response?.statusCode??200,body:u,headers:s.responseHeaders}}}async function zu(e,n){return await In(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function Ju(e,n){return await ln(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope,authType:n.authType,providerData:n.providerData}),{status:"ok"}}async function Fr(e,n,t){let r=await Br(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Br(e,n,t){let r=v(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 Vu(e,n){try{return await Rt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function Yu(e,n){try{return await Er(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Wi(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Xu(e,n){try{let t=Wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Or({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 Qu(e,n){try{let t=Wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Mr({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 Hn(e,n,t={}){let r=v(e),o=Hr(n.headers,"x-corsair-signature"),i=Hr(n.headers,"x-corsair-timestamp"),s=Hr(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=un({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!l.ok)return{status:"failed",retryable:!1,error:l.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let c=It(`nonce:${s.trim()}`,Me);if(!c.ok)return{status:"failed",retryable:!1,error:c.error};a=!0}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let u;try{u=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(u.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(u.type){case"webhook":return Gu(e,r,u.payload,a);case"oauth.callback":return zu(e,u.payload);case"oauth.tokens":return Ju(e,u.payload);case"permission.approve":return Br(e,u.payload,"approved");case"permission.deny":return Br(e,u.payload,"denied");case"auth.credentials":return Vu(e,u.payload);case"integration.credentials":return Yu(e,u.payload);case"connect.create_link":return qu(e,u.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?Ku(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Xu(e,u.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?Qu(e,u.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(u.type)}`}}}function ec(e){let n=e.webhookResponse;return e.status==="ok"?{status:n?.status??200,body:n?.body??{status:"ok"}}:{status:n?.status??502,body:n?.body??{status:"error",error:e.error??"delivery failed"}}}var Nr=3,nc=250;function tc(e){return e?.name==="AbortError"}async function rc(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function oc(e,n,t,r,o){for(let i=1;i<=Nr;i++){try{let s=await n.fetch(`${e.apiUrl}/api/dev/ack`,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(r),signal:o});if(s.ok)return await rc(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(tc(s))throw s}i<Nr&&await Ki(nc)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Nr} attempts; the run may be retried`),!1}async function ic(e,n,t,r){let o={authorization:`Bearer ${n.projectApiKey}`},i=await t.fetch(`${n.apiUrl}/api/dev/pull`,{headers:o,signal:r});if(i.status===204)return"idle";if(!i.ok)return"error";let{deliveryId:s,body:a,headers:u}=await i.json(),l=await t.process(e,{headers:u,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:c,body:d}=ec(l);return await oc(n,t,o,{deliveryId:s,status:c,body:d},r)?"handled":"error"}var ji=1e3,sc=5e3,ac=3e4;function Ki(e){return new Promise(n=>setTimeout(n,e))}var Ot=globalThis.__corsairConnectLoops??=new Map;function uc(e,n={fetch,process:Hn}){let t;try{t=F(e)}catch{return{stop:()=>{}}}if(!t.projectApiKey.startsWith("ck_dev_"))return{stop:()=>{}};if(!t.allowWorkflowExecution)return console.warn("[corsair] workflow executions not enabled. Please set hub: { ..., allowWorkflowExecution: true }"),{stop:()=>{}};let r=t.projectApiKey;if(Ot.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Ot.set(r,o);let i=()=>{Ot.get(r)===o&&Ot.delete(r)},s=!1,a=null;return(async()=>{let l=ji,c=!1,d=async p=>{c||(console.warn("[corsair] connect loop error; retrying",p),c=!0),s||await Ki(l),l=Math.min(l*2,sc)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),ac);try{await ic(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(c=!1,l=ji)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function qi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function cc(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Zi(e,n,t={}){let r=v(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await An(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>cc(l,i)).map(l=>{let c=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:ve(l.id),authKind:qi(c),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:ve(l.id),authKind:qi(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function Gi(e,n){let t=F(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:jn})}var zi=1024*1024,Ji=3e4;function $e(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:zi}function We(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:Ji}function dn(e){return new P(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function lc(e){return new P(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Mt(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(lc(n)),n)})])}finally{clearTimeout(t)}}async function Ht(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:u}=await Mt(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=u.byteLength,o>n.maxBodyBytes)throw dn(n.maxBodyBytes);r.push(u)}let i=new Uint8Array(o),s=0;for(let a of r)i.set(a,s),s+=a.byteLength;return new TextDecoder().decode(i)}catch(r){throw t.cancel().catch(()=>{}),r}}var Ur=new Map;function Vi(e){let n;try{n=F(e)}catch{return}let t=zt(n);t&&Ur.get(n.projectApiKey)!==t&&(Ur.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Ur.delete(n.projectApiKey)}))}var dc=[".corsair.dev"];function pc(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function gc(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:pc(n)?!0:dc.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Yi(e){return!e||!gc(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 Xi(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 Lr(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 $r(e,n){let t=F(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=Pe(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=It(`browser:${i.jti}`,Te);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Dn(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 En(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Et(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 at(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:u.connectUrl,expiresAt:u.expiresAt}})}}if(Le(i))return i.hubSuccessUrl?i.credentials?(await Rt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:Lr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Lr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(On(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Fr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Mn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await ln(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope,authType:i.authType,providerData:i.providerData})}else{if(!Dt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await In(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 Dn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Et(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Le(i)&&i.hubSuccessUrl?{type:"redirect",url:Lr(i.hubSuccessUrl,{error:u})}:Le(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({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 Wr(e,n){let t=F(e),r=await Hn(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 jr(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 Kr(e,n){return n.method==="GET"?$r(e,n.url):Wr(e,{headers:n.headers,body:n.body??""})}async function qr(e,n){try{let t=await Kr(e,n);return jr(t)}catch(t){if(t instanceof de)return Response.json({error:t.message},{status:503});throw t}}async function je(e,n,t){Vi(e);let r=n.method.toUpperCase(),o=Yi(n.headers.get("origin"));if(r==="OPTIONS")return o?new Response(null,{status:204,headers:o}):Response.json({error:"Method not allowed"},{status:405});if(r!=="GET"&&r!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await qr(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Ht(n,{maxBodyBytes:$e(t?.maxBodyBytes),bodyStallTimeoutMs:We(t?.bodyStallTimeoutMs)}):void 0});return Xi(i,o)}var B=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}};function pn(e){if(e.forceRefresh||!e.accessToken||!e.expiresAt)return!1;let n=e.now??Math.floor(Date.now()/1e3);return Number(e.expiresAt)>n+300}async function gn(e,n,t){let r=Math.floor(Date.now()/1e3),o=t?Number(t):Number.NaN,i=typeof n.expires_in=="number"?r+n.expires_in:Number.isFinite(o)&&o>r?o:r+3600;return await e.set_access_token(n.access_token),await e.set_expires_at(String(i)),n.refresh_token&&await e.set_refresh_token(n.refresh_token),n.scope&&await e.set_scope(n.scope),i}var Qi=new WeakMap;function Bn(e,n,t){let r=Qi.get(e);r||(r=new Map,Qi.set(e,r));let o=r.get(n);if(o!==void 0)return o;let i=t().finally(()=>{r.delete(n)});return r.set(n,i),i}var es=300;async function Zr(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Bn(t,a,async()=>{let[u,l,c]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!u&&!c)throw new B(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&u&&l&&Number(l)>d+es)return{accessToken:u,expiresAt:Number(l),refreshed:!1};if(!c&&u&&!s){let f=l?Number(l):null;if(f===null||f>d+es)return{accessToken:u,expiresAt:f??d+3600,refreshed:!1}}if(!c)throw new B(o,"managed");let p=await yc(r,o,i,c),g=await gn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function fc(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function yc(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:Ze})}catch(o){let i=o instanceof Error?o.message:"";throw fc(i)?new B(n,"managed"):o}}async function ns(e,n){e._refreshAuth=async()=>(await Zr(n,{forceRefresh:!0})).accessToken}function ts(e){return{delivery:n=>je(e,n),deliveryOptions:n=>je(e,n)}}var rs=1200*1e3;function Gr(){return le()}function zr(){return rs}function Jr(e,n){return wn(e,n,rs)}function Vr(e,n){return ie(e,n)}function Yr(e){return He(e)}var os=600*1e3;function Xr(){return le()}function Qr(){return os}function eo(e,n){return wn(e,n,os)}function no(e,n){return ie(e,n)}function to(e){return nr(e)}function ro(e){return He(e)}function oo(){return le()}function io(e,n,t){return Gn(e,n,Math.floor(t.getTime()/1e3))}function so(e,n){return ie(e,n)}function ao(e){return He(e)}var Ke=class extends Error{constructor(){super(`Corsair KEK is missing. Pass \`kek\` to createCorsair() or set CORSAIR_KEK in your environment. Generate one with: openssl rand -base64 ${Be}`),this.name="CorsairKekMissingError"}};function Bt(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){if(e&&!n)throw new Ke;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
48
|
|
|
49
|
-
To generate a KEK, run: openssl rand -base64 ${Be}`)}})}async function hc(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 ss(e){let{integrationId:n,accountId:t}=await hc(e);return{integrationId:n,accountId:t}}function as(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>Vt(t(),{tenantId:n,message:r}),list:()=>Xt(t(),{tenantId:n}),get:r=>({message:o=>Yt(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>Qt(t(),{chatId:r,tenantId:n})})}}function co(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function bc(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await dr(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 kc(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await dr(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}):co(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 bc({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?co(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function wc(e,n,t){let r=Ye(xe(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}):co(e,i)}async function Cc(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&tn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?wc(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?kc({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 us(e){let n=await Cc(e);throw new B(e.error.pluginId,e.error.authType,n)}var vc=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function cs(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||vc)(e,i)}function Tc(e){return typeof e=="function"}function lo({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}){for(let[T,D]of Object.entries(e)){let E=n?.[T];if(Tc(D)){let M=E,w=[...s,T].join("."),A=async(R={})=>{let z=l?.[w];kr(w,z?.riskLevel??"write");let ce;if(u){let J=z,{result:Un,reason:re,onComplete:hn,token:ke,id:Oe,expiresAt:V}=await Ai({pluginId:o,endpointPath:w,args:R,mode:u.mode,override:u.overrides?.[w],riskLevel:J?.riskLevel??"write",meta:J,db:c,timeoutMs:d?wr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(Un==="blocked"){let oe;throw re==="denied"?oe=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:re==="policy"?oe=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:re==="timeout"?oe=`Action '${w}' timed out waiting for approval.`:ke&&Oe?oe=await hr({permissionsOptions:d,manual:g,hub:f,permissionId:Oe,permissionToken:ke,plugin:o,endpoint:w,args:R,tenantId:p??"default",expiresAt:V??new Date(Date.now()+(d?wr(d.timeout):600*1e3)).toISOString(),operationPath:w}):oe=`Action '${w}' requires user approval before it can run.`,new rn(oe)}ce=hn}let S=async(J,Un,re)=>{try{return await D(Un,re)}catch(hn){if(hn instanceof Error){let ke=await cs(hn,o,w,typeof re=="object"&&re!==null?re:{args:re},i);if(J<(ke.maxRetries||0)){let Oe=J+1;console.log(`Retrying (${Oe} / ${ke.maxRetries})...`);let V;if(ke.headersRetryAfterMs)V=ke.headersRetryAfterMs;else switch(ke.retryStrategy){case"exponential_backoff":V=Math.pow(2,Oe-1)*1e3;break;case"exponential_backoff_jitter":let oe=Math.pow(2,Oe-1)*1e3,pa=(Math.random()-.5)*1e3;V=Math.max(0,oe+pa);break;case"linear_1s":V=1e3;break;case"linear_2s":V=2e3;break;case"linear_3s":V=3e3;break;case"linear_4s":V=4e3;break;default:V=1e3;break}return await new Promise(oe=>setTimeout(oe,V)),await S(Oe,Un,re)}}throw hn}},te;try{te=a?await a(t,"endpoint"):void 0}catch(J){throw J instanceof B&&(h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await us({error:J,manual:g,hub:f,plugin:h,tenantId:p,database:c,kek:k,plugins:b,multiTenancy:C})),J}if(!M?.before&&!M?.after){let J=await S(0,{...t,key:te},R);return await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),J}let mn={...t,key:te},De=M.before?await M.before(mn,R):{ctx:mn,args:R,continue:!0,passToAfter:void 0};if(De.continue===!1)return;let xo=await S(0,De.ctx,De.args);return await M.after?.(De.ctx,xo,De.passToAfter),await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),xo};r[T]=A}else if(D&&typeof D=="object"){let M={};lo({endpoints:D,hooks:E,ctx:t,tree:M,pluginId:o,errorHandlers:i,currentPath:[...s,T],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}),r[T]=M}}}function Pc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function po({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Pc(s)){let u=a,l=async c=>{let d=(g,f)=>s.handler(g,f),p=o&&c?.hubVerified!==!0?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?d({...t,key:p},c):(async()=>{let g={...t,key:p},f=u.before?await u.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let h=await d(f.ctx,f.args);return h?.success===!0&&await u.after?.(f.ctx,h,f.passToAfter),h})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let u={};po({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function ls(e){return e&&typeof e=="object"?e:{}}async function ds(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=ls(t).workflows;return Array.isArray(r)?r:[]}})}async function ps(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>ls(t).workflow})}async function gs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function fs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function ys(e,n){return x({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 go(e){return e&&typeof e=="object"?e:{}}async function ms(e,n){return $({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=go(t).runs;return Array.isArray(r)?r:[]}})}async function hs(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=go(t).runs;return Array.isArray(r)?r:[]}})}async function bs(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>go(t).run})}async function fo(e,n,t){await x({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 ks=(e,n)=>fo(e,"approve",n),ws=(e,n)=>fo(e,"deny",n),Cs=(e,n)=>fo(e,"cancel",n);function vs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?hs(t(),{workflowId:r.workflowId,tenantId:n}):ms(t(),{tenantId:n}),get:r=>bs(t(),{runId:r,tenantId:n}),approve:r=>ks(t(),{runId:r,tenantId:n}),deny:r=>ws(t(),{runId:r,tenantId:n}),cancel:r=>Cs(t(),{runId:r,tenantId:n})}}function Ts(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,i)=>gs(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>ds(t(),{tenantId:n}),get:o=>ps(t(),{workflowId:o,tenantId:n}),run:(o,i)=>ys(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:vs(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>fs(t(),{workflowId:o,tenantId:n,name:i})}}function Ac(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 ss({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function Rc(e,n,t,r,o){return e?Zt(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 yo(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",d=l&&t?()=>Ve(l,c):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let h=f.schema,k=Ac(t,f.id,c,d);if(h?.entities){let S={};for(let[te,mn]of Object.entries(h.entities)){let De=t?Zt(t.db,k,te,h.version,mn):Rc(void 0,k,te,h.version,mn);S[te]=De}g[f.id].db=S,p[f.id].db=S}let b=f.options,C=f.authConfig,T;if(t&&o&&b?.authType){let S=C?.[b.authType]?.account??[];T=H({authType:b.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:S,ensureProvisioned:d}),p[f.id].keys=T}let D={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...T?{keys:T,authType:b?.authType}:{},tenantId:c,...u?{hub:u}:{}},E=f.endpoints??{},M=f.hooks,w={...i,...f.errorHandlers},A={},R=f.options?.permissions;lo({endpoints:E,hooks:M,ctx:D,tree:A,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:R,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(A).length>0&&(p[f.id].api=A),D.endpoints=A;let z=f.webhooks??{},ce=f.webhookHooks;if(Object.keys(z).length>0){let S={};po({webhooks:z,hooks:ce,ctx:D,webhooksTree:S,keyBuilder:f.keyBuilder}),p[f.id].webhooks=S,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=as(u,c),p.workflows=Ts(u,c),p}function Ps(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=N({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=u}}return r}var xc="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function As(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] ${xc}`),t):n}var Rs=[{method:"GET",pattern:"/ok",handler:async()=>O(200,pt())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>O(200,await sn(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>O(201,await yt(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>O(200,await ft(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>O(200,await on(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>O(200,await gt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>O(200,await mt(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>O(200,await Cr(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?O(200,await Tr(e,t)):O(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>O(200,await ht(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>O(200,await bt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>O(200,await kt(e,n,t))}];(()=>{let e=new Set;for(let n of Rs){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Ic(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 Sc(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 _c(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Ht(e,n).catch(o=>{throw o instanceof P?o:new P(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new P(400,"invalid_json","Request body is not valid JSON")}}var Ec="/api/corsair";function U(e,n={}){let t=n.basePath??Ec,r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=v(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async a=>{try{let u=a.headers.get("content-length");if(u!==null&&Number(u)>r)throw ln(r);let l=new URL(a.url),c=Sc(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||c==="/"||c==="")return await je(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return O(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of Rs){if(g.method!==d)continue;let f=Ic(g.pattern,c);if(!f)continue;let h=await _c(a,i);return await g.handler({corsair:e,internal:s,req:a,params:f,query:p,body:h})}throw Ie(`No route for ${d} ${c}`)}catch(u){if(n.onError){let c=await n.onError(u,a);if(c)return c}if(u instanceof P)return se(u);let l=u instanceof Error?u.message:"Internal server error";return O(500,{error:"internal_error",message:l})}}}function Dc(e,n){if(e.get)return e.get(n);let t=e.headers[n]??e.headers[n.toLowerCase()];return Array.isArray(t)?t[0]:t}function Oc(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(typeof e=="string")return Buffer.from(e,"utf8");throw new TypeError(`corsair adapter: unsupported stream chunk type ${typeof e}`)}async function Mc(e,n,t){let r=[],o=0,i=e();try{let s=await Mt(()=>i.next(),t);for(;s.done!==!0;){let a=Oc(s.value);if(o+=a.byteLength,o>n)throw ln(n);r.push(a),s=await Mt(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var xs=!1;function Hc(){xs||(xs=!0,console.warn("[corsair] A JSON body parser consumed this request before the corsair adapter.","Re-serializing the parsed object is lossy and will likely fail Hub signature",'verification ("Invalid tunnel signature"). Fix on the corsair route only:',"Express \u2192 mount express.raw({ type: 'application/json' }) before the handler,","or capture raw bytes via express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }).","Fastify \u2192 call registerCorsairRawBodyParser(app) before listen()."))}async function Bc(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i;if(typeof e.rawBody=="string")i=e.rawBody;else if(e.rawBody instanceof Uint8Array)i=e.rawBody;else if(e.body!==void 0&&e.body!==null)typeof e.body=="string"||e.body instanceof Uint8Array?i=e.body:(Hc(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let u=await Mc(a.bind(e),r,o);u.length>0&&(i=u)}if(i===void 0)return;if((typeof i=="string"?Buffer.byteLength(i,"utf8"):i.byteLength)>r)throw ln(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function _e(e,n={}){let t=Dc(e,"host")??"localhost",r=e.protocol??"http",o=e.originalUrl??e.url??"/",i=`${r}://${t}${o}`,s=new Headers;for(let[l,c]of Object.entries(e.headers))if(c!=null&&!Fc.has(l.toLowerCase()))if(Array.isArray(c))for(let d of c)s.append(l,d);else s.set(l,c);let a={method:(e.method??"GET").toUpperCase(),headers:s},u=await Bc(e,n);return u!==void 0&&(a.body=u,s.has("content-type")||s.set("content-type","application/json")),new Request(i,a)}async function q(e,n){typeof e.status=="function"?e.status(n.status):e.statusCode=n.status;let t=n.headers.getSetCookie();n.headers.forEach((o,i)=>{i!=="set-cookie"&&e.setHeader(i,o)}),t.length>0&&e.setHeader("set-cookie",t);let r=Buffer.from(await n.arrayBuffer());e.send?e.send(r):e.end?.(r)}var Fc=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function Is(e,n){let t=U(e,n);return async(r,o,i)=>{try{let s=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,s)}catch(s){if(s instanceof P&&o.headersSent!==!0){await q(o,se(s)),K(r);return}K(r),i(s)}}}function Nc(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function Uc(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Nc(e.headers,"content-type");if(!(!t||!t.includes("application/json"))&&!(e.raw.readableEnded!==!0&&e.raw.complete!==!0))throw new Error("corsair: Fastify consumed this JSON body before the corsair adapter could read it. Call registerCorsairRawBodyParser(app) before listen() so the original bytes reach the adapter verbatim (Hub signs deliveries over the exact bytes it sent).")}function Ss(e){e.addContentTypeParser("application/json",{parseAs:"buffer"},(n,t,r)=>{n.rawBody=t;try{r(null,JSON.parse(t.toString("utf8")))}catch{r(Object.assign(new Error("Invalid JSON body"),{statusCode:400}))}})}function _s(e,n){let t=U(e,n);return async(r,o)=>{Uc(r);let i={method:r.method??r.raw.method,url:r.url??r.raw.url,headers:r.headers,protocol:r.protocol,body:r.body,rawBody:r.rawBody,resume:r.raw.resume?.bind(r.raw),[Symbol.asyncIterator]:r.raw[Symbol.asyncIterator]?.bind(r.raw)};try{let s=await t(await _e(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await q(o.raw,s)}catch(s){if(s instanceof P&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await q(o.raw,se(s)),K(i);return}throw K(i),s}}}function Es(e,n){let t=U(e,n);return r=>t(r.req.raw)}function Ds(e,n){let t=U(e,n);return{GET:t,POST:t,OPTIONS:t}}function Os(e,n){let t=U(e,n);return async(r,o)=>{try{let i=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),K(r);return}if(i instanceof P){await q(o,se(i)),K(r);return}console.error("[corsair] management handler failed:",i),await q(o,O(500,{error:"internal_error"})),K(r)}}}function Nt(e,n){let t=U(e,n);return r=>t(r.request)}function Ms(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Hs(e,n){let t=Nt(e,n);return{loader:t,action:t}}function Bs(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Fs(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ns(e,n){let t=U(e,n);return async r=>{let o={method:r.node.req.method,url:r.node.req.url,headers:r.node.req.headers,protocol:r.node.req.protocol,body:r._body,rawBody:r.node.req.rawBody??r._rawBody,resume:r.node.req.resume?.bind(r.node.req),[Symbol.asyncIterator]:r.node.req[Symbol.asyncIterator]?.bind(r.node.req)};try{let i=await t(await _e(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(r.node.res,i)}catch(i){if(i instanceof P&&r.node.res.headersSent!==!0){await q(r.node.res,se(i)),K(o);return}throw K(o),i}}}function Us(e,n){return U(e,n)}function Ls(e){let n={[Fn]:e};return{ok:pt,tenants:{list:()=>sn(e),create:t=>yt(e,t),get:t=>ft(e,t)},plugins:{list:()=>on(e),get:t=>gt(e,t)},connectionStatus:{get:t=>mt(e,t?.tenantId)},permissions:{get:t=>Ei(e,t)},connect:{createLink:t=>ht(n,e,t),resolve:t=>bt(n,e,t),oauthCallback:t=>kt(n,e,t)}}}async function $s(e,n,t,r,o="pending"){if(!e)return null;try{let i=Oo(),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 Lc(e,n,t,r="pending"){try{let o=await e.$getAccountId();return $s(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as js from"https";import*as Ut from"querystring";var $c=["expires_in","refresh_token_expires_in"];function Ws(e){let n={...e};for(let t of $c){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function Wc(e){try{return Ws(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Ut.parse(e);return!n.access_token&&!n.error?null:Ws({...n})}function rt(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=Ut.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=js.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",h=>{f+=h}),g.on("end",()=>{if(g.statusCode!==200){u(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let h=Wc(f);h?a(h):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>u(new Error(`Request failed: ${g.message}`))),p.write(c),p.end()})}async function Ks(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,[s,a,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(dn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!u)throw new B(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:u},parseResponse:qe}),c=await pn(t,l,a);return{accessToken:l.access_token,expiresAt:c,refreshed:!0}}async function qs(e){let{tokenUrl:n,refreshToken:t,clientSecret:r,clientId:o,tokenAuthMethod:i="body",bodyFormat:s="form",extraParams:a}=e,u={grant_type:"refresh_token",refresh_token:t,...a},l={Accept:"application/json"};i==="basic"?l.Authorization=`Basic ${Buffer.from(`${o??""}:${r}`).toString("base64")}`:i==="basic_secret_only"?l.Authorization=`Basic ${Buffer.from(`${r}:`).toString("base64")}`:(o&&(u.client_id=o),u.client_secret=r),s==="json"?l["Content-Type"]="application/json":l["Content-Type"]="application/x-www-form-urlencoded";let c=await fetch(n,{method:"POST",headers:l,body:s==="json"?JSON.stringify(u):new URLSearchParams(u)});if(!c.ok)throw new Error(`OAuth token refresh failed (${c.status}): ${await c.text()}`);let d=JSON.parse(await c.text());if(typeof d.access_token!="string"||d.access_token.length===0)throw new Error("OAuth token refresh returned no access_token");return{access_token:d.access_token,...typeof d.refresh_token=="string"&&d.refresh_token.length>0?{refresh_token:d.refresh_token}:{},...typeof d.expires_in=="number"?{expires_in:d.expires_in}:{},...typeof d.scope=="string"&&d.scope.length>0?{scope:d.scope}:{}}}async function Zs(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new B(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},c=g=>Bn(e.keys,r,async()=>(await Ks(l,{forceRefresh:g})).accessToken);e._refreshAuth=()=>c(!0);let[d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return dn({accessToken:d,expiresAt:p})?d:c(!1)}let o=t.client_secret,i=t.client_id,s=l=>Bn(e.keys,r,async()=>{let[c,d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at(),e.keys.get_refresh_token()]);if(!l&&dn({accessToken:c,expiresAt:d}))return c;if(!p)throw new B(n.plugin,"oauth_2");let g=await qs({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await pn(e.keys,g,d),g.access_token});e._refreshAuth=()=>s(!0);let[a,u]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return dn({accessToken:a,expiresAt:u})?a:s(!1)}var Gs=" ";function ee(e){let n=e;return n._def??n.def??{}}function ne(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 Q(e){return e.innerType??e.schema??e.out??e.in}function Js(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 Q(e)}}function Vs(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function $t(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function fn(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 Ys(e,n){return e.description??n.description}function jc(e){let n=e;for(;n;){let t=ee(n),r=Ys(n,t);if(r)return r;let o=ne(t);if(wo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Js(t,o);continue}break}}function wo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function Z(e){let n=ee(e),t=ne(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??fn(n)[0]??"unknown");case"ZodEnum":return fn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=Q(n);return r?Z(r):"unknown"}case"ZodNullable":{let r=Q(n);return`${r?Z(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Z(r):"unknown"}case"ZodArray":{let r=Vs(n);if(!r)return"unknown[]";let o=ee(r),i=ne(o)==="ZodUnion",s=Z(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=$t(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let u=ne(ee(a));return`${u==="ZodOptional"||u==="ZodNullable"?s+"?":s}: ${Z(a)}`}).join(", ")} }`}case"ZodUnion":return fn(n).map(r=>Z(r)).join(" | ");case"ZodIntersection":return`${Z(n.left)} & ${Z(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=Js(n,t);return r?Z(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function be(e){let n=ee(e),t=ne(n),r=Ys(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??fn(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=fn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Vs(n);return{kind:"array",optional:!1,description:r,items:o?be(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=$t(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=be(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=fn(n);for(let i of o){let s=ee(i);if(ne(s)==="ZodObject")return{...be(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function qk(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=Ee(s.endpointMeta,a),l=Ee(s.endpointSchemas,a);return!u&&!l?null:{input:l?.input?be(l.input):null,output:l?.output?be(l.output):null,description:u?.description}}var Co=["equals","contains","startsWith","endsWith","in"],Kc=["equals","gt","gte","lt","lte","in"],qc=["equals"],Zc=["equals","before","after","between"];function Xs(e){let n=ee(e);switch(ne(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Xs(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function vo(e){let n=ee(e),t=ne(n);if(wo(t)){let i=Q(n);return i?vo(i):{}}if(t!=="ZodObject")return{};let r=$t(e,n),o={};for(let[i,s]of Object.entries(r)){let a=Xs(s);a==="string"?o[i]={type:"string",operators:Co}:a==="number"?o[i]={type:"number",operators:Kc}:a==="boolean"?o[i]={type:"boolean",operators:qc}:a==="date"&&(o[i]={type:"date",operators:Zc})}return o}function Qs(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function ho(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"&&ho(o,i,t)}}function bo(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ko(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];bo(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&ko(o,i,t)}}function To(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 bo(s)?[i]:null;if(s!==null&&typeof s=="object"&&!bo(s)){let a=To(s,r);if(a!==null)return[i,...a]}return null}function ea(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
|
|
49
|
+
To generate a KEK, run: openssl rand -base64 ${Be}`)}})}async function mc(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 is(e){let{integrationId:n,accountId:t}=await mc(e);return{integrationId:n,accountId:t}}function ss(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>Jt(t(),{tenantId:n,message:r}),list:()=>Yt(t(),{tenantId:n}),get:r=>({message:o=>Vt(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>Xt(t(),{chatId:r,tenantId:n})})}}function uo(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function hc(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await lr(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 bc(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await lr(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}):uo(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 hc({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?uo(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function kc(e,n,t){let r=Xe(xe(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}):uo(e,i)}async function wc(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&rn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?kc(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?bc({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 as(e){let n=await wc(e);throw new B(e.error.pluginId,e.error.authType,n)}var Cc=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function us(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||Cc)(e,i)}function vc(e){return typeof e=="function"}function co({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}){for(let[T,D]of Object.entries(e)){let E=n?.[T];if(vc(D)){let M=E,w=[...s,T].join("."),A=async(R={})=>{let z=l?.[w];br(w,z?.riskLevel??"write");let ce;if(u){let J=z,{result:Un,reason:re,onComplete:hn,token:ke,id:Oe,expiresAt:V}=await Pi({pluginId:o,endpointPath:w,args:R,mode:u.mode,override:u.overrides?.[w],riskLevel:J?.riskLevel??"write",meta:J,db:c,timeoutMs:d?kr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(Un==="blocked"){let oe;throw re==="denied"?oe=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:re==="policy"?oe=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:re==="timeout"?oe=`Action '${w}' timed out waiting for approval.`:ke&&Oe?oe=await mr({permissionsOptions:d,manual:g,hub:f,permissionId:Oe,permissionToken:ke,plugin:o,endpoint:w,args:R,tenantId:p??"default",expiresAt:V??new Date(Date.now()+(d?kr(d.timeout):600*1e3)).toISOString(),operationPath:w}):oe=`Action '${w}' requires user approval before it can run.`,new on(oe)}ce=hn}let S=async(J,Un,re)=>{try{return await D(Un,re)}catch(hn){if(hn instanceof Error){let ke=await us(hn,o,w,typeof re=="object"&&re!==null?re:{args:re},i);if(J<(ke.maxRetries||0)){let Oe=J+1;console.log(`Retrying (${Oe} / ${ke.maxRetries})...`);let V;if(ke.headersRetryAfterMs)V=ke.headersRetryAfterMs;else switch(ke.retryStrategy){case"exponential_backoff":V=Math.pow(2,Oe-1)*1e3;break;case"exponential_backoff_jitter":let oe=Math.pow(2,Oe-1)*1e3,da=(Math.random()-.5)*1e3;V=Math.max(0,oe+da);break;case"linear_1s":V=1e3;break;case"linear_2s":V=2e3;break;case"linear_3s":V=3e3;break;case"linear_4s":V=4e3;break;default:V=1e3;break}return await new Promise(oe=>setTimeout(oe,V)),await S(Oe,Un,re)}}throw hn}},te;try{te=a?await a(t,"endpoint"):void 0}catch(J){throw J instanceof B&&(h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await as({error:J,manual:g,hub:f,plugin:h,tenantId:p,database:c,kek:k,plugins:b,multiTenancy:C})),J}if(!M?.before&&!M?.after){let J=await S(0,{...t,key:te},R);return await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),J}let mn={...t,key:te},De=M.before?await M.before(mn,R):{ctx:mn,args:R,continue:!0,passToAfter:void 0};if(De.continue===!1)return;let Ro=await S(0,De.ctx,De.args);return await M.after?.(De.ctx,Ro,De.passToAfter),await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),Ro};r[T]=A}else if(D&&typeof D=="object"){let M={};co({endpoints:D,hooks:E,ctx:t,tree:M,pluginId:o,errorHandlers:i,currentPath:[...s,T],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}),r[T]=M}}}function Tc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function lo({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Tc(s)){let u=a,l=async c=>{let d=(g,f)=>s.handler(g,f),p=o&&c?.hubVerified!==!0?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?d({...t,key:p},c):(async()=>{let g={...t,key:p},f=u.before?await u.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let h=await d(f.ctx,f.args);return h?.success===!0&&await u.after?.(f.ctx,h,f.passToAfter),h})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let u={};lo({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function cs(e){return e&&typeof e=="object"?e:{}}async function ls(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=cs(t).workflows;return Array.isArray(r)?r:[]}})}async function ds(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>cs(t).workflow})}async function ps(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function gs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function fs(e,n){return x({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 po(e){return e&&typeof e=="object"?e:{}}async function ys(e,n){return $({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=po(t).runs;return Array.isArray(r)?r:[]}})}async function ms(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=po(t).runs;return Array.isArray(r)?r:[]}})}async function hs(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>po(t).run})}async function go(e,n,t){await x({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 bs=(e,n)=>go(e,"approve",n),ks=(e,n)=>go(e,"deny",n),ws=(e,n)=>go(e,"cancel",n);function Cs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?ms(t(),{workflowId:r.workflowId,tenantId:n}):ys(t(),{tenantId:n}),get:r=>hs(t(),{runId:r,tenantId:n}),approve:r=>bs(t(),{runId:r,tenantId:n}),deny:r=>ks(t(),{runId:r,tenantId:n}),cancel:r=>ws(t(),{runId:r,tenantId:n})}}function vs(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,i)=>ps(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>ls(t(),{tenantId:n}),get:o=>ds(t(),{workflowId:o,tenantId:n}),run:(o,i)=>fs(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:Cs(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>gs(t(),{workflowId:o,tenantId:n,name:i})}}function Pc(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 is({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function Ac(e,n,t,r,o){return e?qt(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 fo(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",d=l&&t?()=>Ye(l,c):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let h=f.schema,k=Pc(t,f.id,c,d);if(h?.entities){let S={};for(let[te,mn]of Object.entries(h.entities)){let De=t?qt(t.db,k,te,h.version,mn):Ac(void 0,k,te,h.version,mn);S[te]=De}g[f.id].db=S,p[f.id].db=S}let b=f.options,C=f.authConfig,T;if(t&&o&&b?.authType){let S=C?.[b.authType]?.account??[];T=H({authType:b.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:S,ensureProvisioned:d}),p[f.id].keys=T}let D={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...T?{keys:T,authType:b?.authType}:{},tenantId:c,...u?{hub:u}:{}},E=f.endpoints??{},M=f.hooks,w={...i,...f.errorHandlers},A={},R=f.options?.permissions;co({endpoints:E,hooks:M,ctx:D,tree:A,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:R,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(A).length>0&&(p[f.id].api=A),D.endpoints=A;let z=f.webhooks??{},ce=f.webhookHooks;if(Object.keys(z).length>0){let S={};lo({webhooks:z,hooks:ce,ctx:D,webhooksTree:S,keyBuilder:f.keyBuilder}),p[f.id].webhooks=S,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=ss(u,c),p.workflows=vs(u,c),p}function Ts(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=N({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=u}}return r}var Rc="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Ps(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] ${Rc}`),t):n}var As=[{method:"GET",pattern:"/ok",handler:async()=>O(200,pt())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>O(200,await an(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>O(201,await yt(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>O(200,await ft(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>O(200,await sn(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>O(200,await gt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>O(200,await mt(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>O(200,await wr(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?O(200,await vr(e,t)):O(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>O(200,await ht(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>O(200,await bt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>O(200,await kt(e,n,t))}];(()=>{let e=new Set;for(let n of As){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function xc(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 Ic(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 Sc(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Ht(e,n).catch(o=>{throw o instanceof P?o:new P(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new P(400,"invalid_json","Request body is not valid JSON")}}var _c="/api/corsair";function U(e,n={}){let t=n.basePath??_c,r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=v(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async a=>{try{let u=a.headers.get("content-length");if(u!==null&&Number(u)>r)throw dn(r);let l=new URL(a.url),c=Ic(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||c==="/"||c==="")return await je(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return O(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of As){if(g.method!==d)continue;let f=xc(g.pattern,c);if(!f)continue;let h=await Sc(a,i);return await g.handler({corsair:e,internal:s,req:a,params:f,query:p,body:h})}throw Ie(`No route for ${d} ${c}`)}catch(u){if(n.onError){let c=await n.onError(u,a);if(c)return c}if(u instanceof P)return se(u);let l=u instanceof Error?u.message:"Internal server error";return O(500,{error:"internal_error",message:l})}}}function Ec(e,n){if(e.get)return e.get(n);let t=e.headers[n]??e.headers[n.toLowerCase()];return Array.isArray(t)?t[0]:t}function Dc(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(typeof e=="string")return Buffer.from(e,"utf8");throw new TypeError(`corsair adapter: unsupported stream chunk type ${typeof e}`)}async function Oc(e,n,t){let r=[],o=0,i=e();try{let s=await Mt(()=>i.next(),t);for(;s.done!==!0;){let a=Dc(s.value);if(o+=a.byteLength,o>n)throw dn(n);r.push(a),s=await Mt(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var Rs=!1;function Mc(){Rs||(Rs=!0,console.warn("[corsair] A JSON body parser consumed this request before the corsair adapter.","Re-serializing the parsed object is lossy and will likely fail Hub signature",'verification ("Invalid tunnel signature"). Fix on the corsair route only:',"Express \u2192 mount express.raw({ type: 'application/json' }) before the handler,","or capture raw bytes via express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }).","Fastify \u2192 call registerCorsairRawBodyParser(app) before listen()."))}async function Hc(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i;if(typeof e.rawBody=="string")i=e.rawBody;else if(e.rawBody instanceof Uint8Array)i=e.rawBody;else if(e.body!==void 0&&e.body!==null)typeof e.body=="string"||e.body instanceof Uint8Array?i=e.body:(Mc(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let u=await Oc(a.bind(e),r,o);u.length>0&&(i=u)}if(i===void 0)return;if((typeof i=="string"?Buffer.byteLength(i,"utf8"):i.byteLength)>r)throw dn(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function _e(e,n={}){let t=Ec(e,"host")??"localhost",r=e.protocol??"http",o=e.originalUrl??e.url??"/",i=`${r}://${t}${o}`,s=new Headers;for(let[l,c]of Object.entries(e.headers))if(c!=null&&!Bc.has(l.toLowerCase()))if(Array.isArray(c))for(let d of c)s.append(l,d);else s.set(l,c);let a={method:(e.method??"GET").toUpperCase(),headers:s},u=await Hc(e,n);return u!==void 0&&(a.body=u,s.has("content-type")||s.set("content-type","application/json")),new Request(i,a)}async function q(e,n){typeof e.status=="function"?e.status(n.status):e.statusCode=n.status;let t=n.headers.getSetCookie();n.headers.forEach((o,i)=>{i!=="set-cookie"&&e.setHeader(i,o)}),t.length>0&&e.setHeader("set-cookie",t);let r=Buffer.from(await n.arrayBuffer());e.send?e.send(r):e.end?.(r)}var Bc=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function xs(e,n){let t=U(e,n);return async(r,o,i)=>{try{let s=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,s)}catch(s){if(s instanceof P&&o.headersSent!==!0){await q(o,se(s)),K(r);return}K(r),i(s)}}}function Fc(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function Nc(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Fc(e.headers,"content-type");if(!(!t||!t.includes("application/json"))&&!(e.raw.readableEnded!==!0&&e.raw.complete!==!0))throw new Error("corsair: Fastify consumed this JSON body before the corsair adapter could read it. Call registerCorsairRawBodyParser(app) before listen() so the original bytes reach the adapter verbatim (Hub signs deliveries over the exact bytes it sent).")}function Is(e){e.addContentTypeParser("application/json",{parseAs:"buffer"},(n,t,r)=>{n.rawBody=t;try{r(null,JSON.parse(t.toString("utf8")))}catch{r(Object.assign(new Error("Invalid JSON body"),{statusCode:400}))}})}function Ss(e,n){let t=U(e,n);return async(r,o)=>{Nc(r);let i={method:r.method??r.raw.method,url:r.url??r.raw.url,headers:r.headers,protocol:r.protocol,body:r.body,rawBody:r.rawBody,resume:r.raw.resume?.bind(r.raw),[Symbol.asyncIterator]:r.raw[Symbol.asyncIterator]?.bind(r.raw)};try{let s=await t(await _e(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await q(o.raw,s)}catch(s){if(s instanceof P&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await q(o.raw,se(s)),K(i);return}throw K(i),s}}}function _s(e,n){let t=U(e,n);return r=>t(r.req.raw)}function Es(e,n){let t=U(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ds(e,n){let t=U(e,n);return async(r,o)=>{try{let i=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),K(r);return}if(i instanceof P){await q(o,se(i)),K(r);return}console.error("[corsair] management handler failed:",i),await q(o,O(500,{error:"internal_error"})),K(r)}}}function Ft(e,n){let t=U(e,n);return r=>t(r.request)}function Os(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ms(e,n){let t=Ft(e,n);return{loader:t,action:t}}function Hs(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Bs(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Fs(e,n){let t=U(e,n);return async r=>{let o={method:r.node.req.method,url:r.node.req.url,headers:r.node.req.headers,protocol:r.node.req.protocol,body:r._body,rawBody:r.node.req.rawBody??r._rawBody,resume:r.node.req.resume?.bind(r.node.req),[Symbol.asyncIterator]:r.node.req[Symbol.asyncIterator]?.bind(r.node.req)};try{let i=await t(await _e(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(r.node.res,i)}catch(i){if(i instanceof P&&r.node.res.headersSent!==!0){await q(r.node.res,se(i)),K(o);return}throw K(o),i}}}function Ns(e,n){return U(e,n)}function Us(e){let n={[Fn]:e};return{ok:pt,tenants:{list:()=>an(e),create:t=>yt(e,t),get:t=>ft(e,t)},plugins:{list:()=>sn(e),get:t=>gt(e,t)},connectionStatus:{get:t=>mt(e,t?.tenantId)},permissions:{get:t=>_i(e,t)},connect:{createLink:t=>ht(n,e,t),resolve:t=>bt(n,e,t),oauthCallback:t=>kt(n,e,t)}}}async function Ls(e,n,t,r,o="pending"){if(!e)return null;try{let i=Do(),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 Uc(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Ls(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Ws from"https";import*as Nt from"querystring";var Lc=["expires_in","refresh_token_expires_in"];function $s(e){let n={...e};for(let t of Lc){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function $c(e){try{return $s(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Nt.parse(e);return!n.access_token&&!n.error?null:$s({...n})}function rt(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=Nt.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=Ws.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",h=>{f+=h}),g.on("end",()=>{if(g.statusCode!==200){u(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let h=$c(f);h?a(h):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>u(new Error(`Request failed: ${g.message}`))),p.write(c),p.end()})}async function js(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,[s,a,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(pn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!u)throw new B(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:u},parseResponse:Ze}),c=await gn(t,l,a);return{accessToken:l.access_token,expiresAt:c,refreshed:!0}}async function Ks(e){let{tokenUrl:n,refreshToken:t,clientSecret:r,clientId:o,tokenAuthMethod:i="body",bodyFormat:s="form",extraParams:a}=e,u={grant_type:"refresh_token",refresh_token:t,...a},l={Accept:"application/json"};i==="basic"?l.Authorization=`Basic ${Buffer.from(`${o??""}:${r}`).toString("base64")}`:i==="basic_secret_only"?l.Authorization=`Basic ${Buffer.from(`${r}:`).toString("base64")}`:(o&&(u.client_id=o),u.client_secret=r),s==="json"?l["Content-Type"]="application/json":l["Content-Type"]="application/x-www-form-urlencoded";let c=await fetch(n,{method:"POST",headers:l,body:s==="json"?JSON.stringify(u):new URLSearchParams(u)});if(!c.ok)throw new Error(`OAuth token refresh failed (${c.status}): ${await c.text()}`);let d=JSON.parse(await c.text());if(typeof d.access_token!="string"||d.access_token.length===0)throw new Error("OAuth token refresh returned no access_token");return{access_token:d.access_token,...typeof d.refresh_token=="string"&&d.refresh_token.length>0?{refresh_token:d.refresh_token}:{},...typeof d.expires_in=="number"?{expires_in:d.expires_in}:{},...typeof d.scope=="string"&&d.scope.length>0?{scope:d.scope}:{}}}async function qs(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new B(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},c=g=>Bn(e.keys,r,async()=>(await js(l,{forceRefresh:g})).accessToken);e._refreshAuth=()=>c(!0);let[d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return pn({accessToken:d,expiresAt:p})?d:c(!1)}let o=t.client_secret,i=t.client_id,s=l=>Bn(e.keys,r,async()=>{let[c,d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at(),e.keys.get_refresh_token()]);if(!l&&pn({accessToken:c,expiresAt:d}))return c;if(!p)throw new B(n.plugin,"oauth_2");let g=await Ks({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await gn(e.keys,g,d),g.access_token});e._refreshAuth=()=>s(!0);let[a,u]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return pn({accessToken:a,expiresAt:u})?a:s(!1)}var Zs=" ";function ee(e){let n=e;return n._def??n.def??{}}function ne(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 Q(e){return e.innerType??e.schema??e.out??e.in}function zs(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 Q(e)}}function Js(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Lt(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function fn(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 Vs(e,n){return e.description??n.description}function Wc(e){let n=e;for(;n;){let t=ee(n),r=Vs(n,t);if(r)return r;let o=ne(t);if(ko(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=zs(t,o);continue}break}}function ko(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function Z(e){let n=ee(e),t=ne(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??fn(n)[0]??"unknown");case"ZodEnum":return fn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=Q(n);return r?Z(r):"unknown"}case"ZodNullable":{let r=Q(n);return`${r?Z(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Z(r):"unknown"}case"ZodArray":{let r=Js(n);if(!r)return"unknown[]";let o=ee(r),i=ne(o)==="ZodUnion",s=Z(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Lt(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let u=ne(ee(a));return`${u==="ZodOptional"||u==="ZodNullable"?s+"?":s}: ${Z(a)}`}).join(", ")} }`}case"ZodUnion":return fn(n).map(r=>Z(r)).join(" | ");case"ZodIntersection":return`${Z(n.left)} & ${Z(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=zs(n,t);return r?Z(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function be(e){let n=ee(e),t=ne(n),r=Vs(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??fn(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=fn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Js(n);return{kind:"array",optional:!1,description:r,items:o?be(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Lt(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=be(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=fn(n);for(let i of o){let s=ee(i);if(ne(s)==="ZodObject")return{...be(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function qk(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=Ee(s.endpointMeta,a),l=Ee(s.endpointSchemas,a);return!u&&!l?null:{input:l?.input?be(l.input):null,output:l?.output?be(l.output):null,description:u?.description}}var wo=["equals","contains","startsWith","endsWith","in"],jc=["equals","gt","gte","lt","lte","in"],Kc=["equals"],qc=["equals","before","after","between"];function Ys(e){let n=ee(e);switch(ne(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Ys(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Co(e){let n=ee(e),t=ne(n);if(ko(t)){let i=Q(n);return i?Co(i):{}}if(t!=="ZodObject")return{};let r=Lt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=Ys(s);a==="string"?o[i]={type:"string",operators:wo}:a==="number"?o[i]={type:"number",operators:jc}:a==="boolean"?o[i]={type:"boolean",operators:Kc}:a==="date"&&(o[i]={type:"date",operators:qc})}return o}function Xs(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function mo(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"&&mo(o,i,t)}}function ho(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function bo(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];ho(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&bo(o,i,t)}}function vo(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 ho(s)?[i]:null;if(s!==null&&typeof s=="object"&&!ho(s)){let a=vo(s,r);if(a!==null)return[i,...a]}return null}function Qs(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 Zc=new Set($n);function qe(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 Zc.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:qe(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return bo(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 mo(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=[];bo(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=[];mo(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Ee(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function Gc(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 yo(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
51
51
|
${e.join(", ")}`:`${n}:
|
|
52
52
|
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
53
|
-
`)}function Zk(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),d=c.lastIndexOf(".");if(d!==-1){let p=c.slice(0,d),g=c.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let h=
|
|
54
|
-
`)}}}return
|
|
55
|
-
${
|
|
53
|
+
`)}function Zk(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),d=c.lastIndexOf(".");if(d!==-1){let p=c.slice(0,d),g=c.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let h=Xs(f,p);if(h){let[k,b]=h,C=Co(b),T=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${wo.join(", ")}]`];for(let[D,E]of Object.entries(C))T.push(` ${D}?: ${E.type} [${E.operators.join(", ")}]`);return T.push("}"),T.join(`
|
|
54
|
+
`)}}}return yo(qe(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let d=vo(s.webhooks,c.split("."));if(d!==null){let p=d.join("."),g=Ee(s.webhookSchemas,p.toLowerCase()),f=g?.response?Z(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${Ut(yn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
|
|
55
|
+
${Qs(o,d)}`),h.join(`
|
|
56
56
|
|
|
57
|
-
`)}}return
|
|
57
|
+
`)}}return yo(qe(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Ee(s.endpointMeta,a),l=Ee(s.endpointSchemas,a);if(u||l){let c=[],d=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),p=[u?.description,d].filter(Boolean).join(" ");return p&&c.push(p),l?.input&&c.push(`input ${Ut(yn(l.input))}`),l?.output&&c.push(`output ${Ut(yn(l.output))}`),c.join(`
|
|
58
58
|
|
|
59
|
-
`)}}}return
|
|
59
|
+
`)}}}return yo(qe(e),"Path not found. Available operations")}function Gs(e){let n=e;for(;;){let t=ee(n),r=ne(t);if(ko(r)){let o=Q(t);if(!o)return n;n=o;continue}return n}}function yn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Gs(e),t=ee(n);if(ne(t)==="ZodObject"){let o=Lt(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=ee(a),l=ne(u),c=l==="ZodOptional"||l==="ZodNullable",d=Gs(a),p=Wc(a);i.push({key:s,optional:c,type:Z(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:Z(n)}}function Ut(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=Zs.repeat(n+1),r=Zs.repeat(n);return`{
|
|
60
60
|
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
61
|
`)}
|
|
62
|
-
${r}}`}return"unknown"}function
|
|
63
|
-
`)}function
|
|
64
|
-
Schema: ${JSON.stringify(
|
|
62
|
+
${r}}`}return"unknown"}function zc(e,n){let t=qe(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(c=>c.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of t){let{shortPath:d,lookupKey:p}=Gc(c,n),g=Ee(r.endpointMeta,p),f=Ee(r.endpointSchemas,p);!g&&!f||o.push({path:c,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:yn(f?.input),output:yn(f?.output)})}o.sort((c,d)=>c.path.localeCompare(d.path));let i=[],s=qe(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=vo(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Ee(r.webhookSchemas,k.toLowerCase()),C=b?.response?Z(b.response):void 0;i.push({path:c,description:b?.description,payload:yn(b?.payload),responseType:C,usageExample:Qs(n,h)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=qe(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=Xs(l,k);if(!C)continue;let[T,D]=C,E=Co(D),M=Object.entries(E).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:c,entityName:T,filters:[{field:"entity_id",type:"string",operators:wo},...M]})}return a.sort((c,d)=>c.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as ea}from"crypto";async function Jc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=ea(),o=ea(),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 Vc}from"crypto";var $t="https://graph.microsoft.com/v1.0",To=2e4,Yc=60;async function Xc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${$t}/subscriptions`,{headers:r,signal:AbortSignal.timeout(To)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${$t}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(To)}).catch(()=>{})))}}catch{}let o=Vc(),i=new Date(Date.now()+Yc*6e4).toISOString(),s=await fetch(`${$t}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(To),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 na(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Qc(e,n){let t=na(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 el(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ta(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ra(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 Nn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function nl(e){return Nn(e.body)}function oa(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Wt(Array.isArray(r)?r:[r])}function ia(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=Wt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=oa({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let u of o){let l=n[u],c=Array.isArray(l)?l[0]:l;if(!(!c||typeof c!="string"))try{let p=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Nn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return Wt([s?.validationToken])??null}function tl(e){if(ia(e))return!0;let n=Nn(e.body??e.payload);return ta(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Wt(e){for(let n of e){let t=ra(n);if(t)return t}}function rl(e){let t=Nn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Fn=Symbol.for("corsair:internal");function ua(e){let n=e.database?xo(e.database):void 0,t=e.kek,r=n&&t?Ts(e.plugins,n,t):Bt(!!n,!!t),o=Ps(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?zn(e.hub):void 0},s=Ti(n),a=Us(i);if(e.multiTenancy){let c=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=fo(e.plugins,{database:n,tenantId:d,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i});return Object.assign(p,{[Fn]:i})},keys:r,permissions:s,manage:a},{[Fn]:i});return sa(c,i.hub),aa(c,i.hub),c}let u=fo(e.plugins,{database:n,tenantId:void 0,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i}),l=Object.assign({},u,{keys:r,permissions:s,manage:a,[Fn]:i});return sa(l,i.hub),aa(l,i.hub),l}function sa(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-C3QS4HV3.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function ol(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var jt=globalThis.__corsairTunnels??=new Set;function aa(e,n){if(!ol(n))return;let t=n.projectApiKey;if(jt.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}jt.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Zt;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>jt.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${Gt}`)}).catch(s=>{jt.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var il={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:{}}}},Po=il;async function ot(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=So(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=hl(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await wl(c,i);let d=await Cl(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Pl(e,u,n.credentials,l,o,i);let p=await Rl(d,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ua({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await xl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function Ao(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...L[n][t],...r])}function ml(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(a=>a.id===t);if(!o)continue;let i=I(o);if(!i)continue;let s=Ao(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function hl(e,n,t){let r=_o(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&&ml(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 la(e,n){return Ce(e)?n===0?!0:Object.values(e).every(t=>la(t,n-1)):!1}function bl(e){return la(e,4)}var kl={...Oo};function Kt(e){if(e instanceof dl){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof yl?Kt(r):"unknown";return n}return e instanceof cl?`${Kt(e.unwrap())} | null`:e instanceof pl?`${Kt(e.unwrap())} | undefined`:e instanceof ul?e.options.join(" | "):e instanceof fl?"string":e instanceof ll?"number":e instanceof sl?"boolean":e instanceof al?"date":e instanceof gl?"jsonb":"unknown"}async function wl(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(kl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(Kt(i),null,2)}`)}async function Cl(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=I(a),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?N({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(c&&!c.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${u}`)),!c||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!h){let k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:c.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).executeTakeFirst(),o(`[corsair:setup] Created account: ${u}`)}f=h&&H({authType:l,integrationName:u,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),h&&f&&!h.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${u}`))}s.set(u,{pluginId:u,authType:l,integration:g,account:f,integrationFields:[...L[l].integration,...d],accountFields:r?[...L[l].account,...p]:[]})}return s}function vl(e){if(!Ce(e))return;let n=e.keys;return Ce(n)?n:void 0}function Tl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Pl(e,n,t,r,o,i){let s=vl(e),a=n.provisionAccounts?Tl(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(b=>b.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let d=I(c);if(!d){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let p=Ao(c,d,"integration"),g=Ao(c,d,"account"),f=s?.[u],h=a?.[u],k=Ce(h)?h.keys:void 0;for(let[b,C]of Object.entries(l))if(C){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${u}.${b}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let T=G(f,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set integration field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${b}' on a multi-tenant instance`);let T=G(k,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set account field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${u}'.`)}}}var ca=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Al(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let p of o){if(ca.has(p))continue;let g=G(t,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(ca.has(p))continue;let g=G(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||c.push(p)}let d=l.length===0&&c.length===0;if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...c];if(u==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
65
|
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of c){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
|
|
66
|
-
`))}}return d}async function
|
|
66
|
+
`))}}return d}async function Rl(e,n,t,r){let o=new Set;for(let i of e.values())await Al(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function xl(e,n,t,r,o){if(!bl(Po)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Po,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=Ce(e)?e[a]:void 0,c=Ce(l)?l.api:void 0;if(c)for(let[d,p]of Object.entries(u))for(let[g,f]of Object.entries(p)){r(`[corsair:setup] Backfilling ${a} \u203A ${d}.${g}...`);try{let h=Ce(c)?c[d]:void 0;await G(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{Ho as a,ve as b,Wn as c,jn as d,Kn as e,Ze as f,Bo as g,qn as h,er as i,bn as j,Wo as k,jo as l,Te as m,Me as n,le as o,ze as p,Je as q,Pe as r,tr as s,qo as t,Cn as u,de as v,vn as w,rr as x,zn as y,F as z,Jn as A,Ve as B,pe as C,ge as D,Y as E,or as F,Tn as G,Ae as H,fe as I,Pn as J,N as K,H as L,Xo as M,Qo as N,ot as O,Pl as P,xe as Q,sr as R,Qe as S,en as T,ur as U,tt as V,ci as W,Ne as X,j as Y,cr as Z,In as _,gi as $,za as aa,it as ba,Np as ca,mi as da,hi as ea,bi as fa,lr as ga,st as ha,dr as ia,ut as ja,ct as ka,on as la,dt as ma,hr as na,vi as oa,br as pa,Pr as qa,Ar as ra,wt as sa,Rr as ta,un as ua,cn as va,Ct as wa,vt as xa,Sn as ya,xr as za,Ir as Aa,Tt as Ba,_n as Ca,Pt as Da,At as Ea,Se as Fa,ln as Ga,Bi as Ha,Or as Ia,Mr as Ja,Le as Ka,On as La,Mn as Ma,Dt as Na,Fr as Oa,Hn as Pa,ec as Qa,ic as Ra,uc as Sa,Zi as Ta,Gi as Ua,zi as Va,Ji as Wa,$e as Xa,We as Ya,$r as Za,Wr as _a,jr as $a,Kr as ab,qr as bb,je as cb,B as db,Zr as eb,ns as fb,ts as gb,Gr as hb,zr as ib,Jr as jb,Vr as kb,Yr as lb,Xr as mb,Qr as nb,eo as ob,no as pb,to as qb,ro as rb,oo as sb,io as tb,so as ub,ao as vb,Ke as wb,U as xb,xs as yb,Is as zb,Ss as Ab,_s as Bb,Es as Cb,Ds as Db,Os as Eb,Ms as Fb,Hs as Gb,Bs as Hb,Fs as Ib,Ns as Jb,Ls as Kb,Uc as Lb,rt as Mb,qs as Nb,qk as Ob,qe as Pb,Zk as Qb,Ut as Rb,zc as Sb,Jc as Tb,$t as Ub,Xc as Vb,na as Wb,Qc as Xb,el as Yb,ta as Zb,ra as _b,Nn as $b,nl as ac,oa as bc,ia as cc,tl as dc,Wt as ec,rl as fc,Fn as gc,ua as hc,ol as ic};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fa as a,ga as b,ha as c}from"./chunk-
|
|
1
|
+
import{fa as a,ga as b,ha as c}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$b as L,C as d,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,Kb as x,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,Rb as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,cc as O,db as v,dc as P,ec as Q,fc as R,gc as S,hc as T,ia as p,ic as U,la as q,ma as r,na as s,oa as t,pa as u,wb as w}from"./chunk-
|
|
1
|
+
import{$b as L,C as d,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,Kb as x,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,Rb as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,cc as O,db as v,dc as P,ec as Q,fc as R,gc as S,hc as T,ia as p,ic as U,la as q,ma as r,na as s,oa as t,pa as u,wb as w}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import{h as c}from"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{v as AuthMissingError,c as BASE_AUTH_FIELDS,S as CORSAIR_INTERNAL,w as CorsairKekMissingError,E as MS_GRAPH_API_BASE,q as PermissionRequiredError,a as ProviderDisplayNames,r as ReadonlyForbiddenError,L as asRecord,u as assertReadonlyAllowed,I as collectPluginWebhookMatchers,m as createAccountKeyManager,T as createCorsair,l as createIntegrationKeyManager,R as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,z as exchangeCodeForTokens,O as extractMicrosoftGraphValidationToken,Q as firstString,B as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,J as getHeader,A as getOAuthAccessToken,D as googleChannelSubscribe,o as initializeAccountDEK,n as initializeIntegrationDEK,C as introspectPluginForDocs,P as isMicrosoftGraphValidationHandshake,t as isReadonlyScopeActive,x as logEvent,y as logEventFromContext,G as matchWebhookPlugin,H as matchWebhookPluginAndTenant,F as msGraphSubscribe,k as reEncryptConfig,M as readBodyRecord,N as readQueryParam,p as resolveConnectLink,s as runReadonly,U as shouldStartTunnel,K as toExternalId};
|
package/dist/hub.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$a as $,A,Aa as Q,B,Ba as R,Ca as S,Da as T,Ea as U,Fa as V,Ga as W,S as C,Ta as X,Ua as Y,Za as Z,_a as _,ab as aa,b as a,bb as ba,c as b,cb as ca,d as c,e as d,eb as da,f as e,fb as ea,g as f,gb as fa,h as g,ha as D,hb as ga,i,ib as ha,j,ja as E,jb as ia,k,ka as F,kb as ja,l,lb as ka,m,mb as la,n,nb as ma,o,ob as na,p,pb as oa,q,qa as G,qb as pa,r,ra as H,rb as qa,s,sa as I,sb as ra,t,ta as J,tb as sa,u,ua as K,ub as ta,v,va as L,vb as ua,w,wa as M,x,xa as N,y,ya as O,z,za as P}from"./chunk-
|
|
1
|
+
import{$a as $,A,Aa as Q,B,Ba as R,Ca as S,Da as T,Ea as U,Fa as V,Ga as W,S as C,Ta as X,Ua as Y,Za as Z,_a as _,ab as aa,b as a,bb as ba,c as b,cb as ca,d as c,e as d,eb as da,f as e,fb as ea,g as f,gb as fa,h as g,ha as D,hb as ga,i,ib as ha,j,ja as E,jb as ia,k,ka as F,kb as ja,l,lb as ka,m,mb as la,n,nb as ma,o,ob as na,p,pb as oa,q,qa as G,qb as pa,r,ra as H,rb as qa,s,sa as I,sb as ra,t,ta as J,tb as sa,u,ua as K,ub as ta,v,va as L,vb as ua,w,wa as M,x,xa as N,y,ya as O,z,za as P}from"./chunk-IXPIBTH2.js";import{a as h,b as va,c as wa,d as xa,e as ya,f as za}from"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{m as BROWSER_DELIVERY_TTL_MS,wa as CORSAIR_TUNNEL_PATH,va as CORSAIR_TUNNEL_ZONE,u as DEFAULT_HUB_API_URL,xa as FRPC_VERSION,w as HubCredentialsMissingError,v as HubNotConfiguredError,V as ManagedOAuthDeliveryError,n as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ea as attachManagedRefreshAuth,p as buildBrowserDeliveryRedirectUrl,s as buildClientBridgeBrowserDeliveryUrl,ga as createConnectSessionJti,la as createConnectTokenJti,D as createHubConnectSession,E as createHubPermissionSession,fa as createHubRouteHandlers,ra as createPermissionSessionJti,o as createSignedTokenJti,ka as decodeConnectSessionTokenFromPath,qa as decodeConnectTokenFromPath,ua as decodePermissionTokenFromPath,Q as deliverConnectCreateLink,U as deliverSignedEnvelope,S as describeDeliveryNetworkError,pa as encodeConnectTokenForPath,O as extractConnectLinkFromDeliveryAck,H as extractProbeFromDeliveryAck,G as extractRunFromDeliveryAck,N as extractSyncFromDeliveryAck,F as formatHubApprovalMessage,a as formatProviderDisplayName,T as formatServerDeliveryError,ya as frpcPlatformKey,ha as getConnectSessionExpiryMs,X as getConnectStatusForTenant,ma as getConnectTokenExpiryMs,z as getHubConfig,da as getManagedAccessToken,Z as handleHubDeliveryGet,_ as handleHubDeliveryPost,aa as handleHubDeliveryRequest,$ as hubDeliveryToResponse,B as inferHubEnvironmentSlug,i as isLoopbackUrl,M as isServerDeliveryAckSuccessful,Y as listHubProjectConnections,x as normalizeHubConfig,P as parseConnectLinkFromDeliveryBody,b as parseConnectSessionResponse,f as parseConnectStatusResponse,g as parseHubApiErrorBody,e as parseOAuthRefreshResponse,d as parsePermissionSessionResponse,c as parseProjectConnectionsResponse,L as parseServerDeliveryAckBody,R as parseSyncFromDeliveryBody,t as prepareClientBridgeDeliveryTransport,W as processManagedOAuthDelivery,C as registerHubWebhookTenantLink,j as resolveDeliveryTransport,za as resolveFrpcBinary,y as resolveHubConfigInput,h as resolveHubDeliveryUrl,A as resolveHubOAuthCallbackUrl,ba as respondToHubDelivery,ca as respondToHubDeliveryFromRequest,q as signBrowserDeliveryToken,ia as signConnectSessionToken,na as signConnectToken,I as signDeliveryEnvelope,sa as signPermissionToken,k as usesBrowserDelivery,l as validateProductionDeliveryUrl,r as verifyBrowserDeliveryToken,ja as verifyConnectSessionToken,oa as verifyConnectToken,J as verifyDeliveryEnvelope,ta as verifyPermissionToken,K as verifySignedTunnelDelivery};
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as ie,b as se}from"./chunk-RQ5QHONV.js";import{$b as ee,Ab as D,Bb as $,Cb as B,Db as j,Eb as Y,Fb as q,Gb as U,Ha as O,Hb as J,Ib as K,Jb as X,O as k,Ob as l,Pa as A,Pb as c,Qb as d,Rb as m,T as x,U as P,V as S,Va as L,W as b,Wa as E,Wb as z,Xa as F,Xb as G,Ya as H,Yb as Q,Zb as V,_b as Z,ac as ne,db as _,ec as re,fc as oe,gc as g,hc as te,ia as w,la as I,ma as T,na as R,wb as v,xb as W,yb as M,zb as N}from"./chunk-
|
|
1
|
+
import{a as ie,b as se}from"./chunk-RQ5QHONV.js";import{$b as ee,Ab as D,Bb as $,Cb as B,Db as j,Eb as Y,Fb as q,Gb as U,Ha as O,Hb as J,Ib as K,Jb as X,O as k,Ob as l,Pa as A,Pb as c,Qb as d,Rb as m,T as x,U as P,V as S,Va as L,W as b,Wa as E,Wb as z,Xa as F,Xb as G,Ya as H,Yb as Q,Zb as V,_b as Z,ac as ne,db as _,ec as re,fc as oe,gc as g,hc as te,ia as w,la as I,ma as T,na as R,wb as v,xb as W,yb as M,zb as N}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";function s(n){let o=n[g];if(!o)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return o.plugins}function ae(n,o){let r=c(s(n),o);return typeof r=="string"?r:Array.isArray(r)?r.join(`
|
|
2
2
|
`):Object.values(r).flat().join(`
|
|
3
3
|
`)}function pe(n,o){return d(s(n),o)}function ue(n,o){return l(s(n),o)}var le=Symbol.for("corsair:internal");function ce(n,o){let r=n;for(let e of o){if(!r||typeof r!="object")return null;r=r[e]}return typeof r=="function"?r:null}function y(n){return n[le]?.database}async function de(n,o){let r=new Date().toISOString(),e=await n.permissions.find_by_token(o);if(!e)return console.error("executePermission: no permission found for token."),{error:"executePermission: no permission found for token."};if(e.status!=="approved")return console.error(`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: permission '${e.id}' is '${e.status}', expected 'approved'.`};if(e.expires_at<r){let t=y(n);return t&&await t.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",e.id).execute(),console.error(`executePermission: permission '${e.id}' has expired.`),{error:`executePermission: permission '${e.id}' has expired.`,endpoint:e.endpoint,plugin:e.plugin,result:null}}let h=e.tenant_id??"default",a=(n.withTenant?n.withTenant(h):n)[e.plugin];if(!a?.api)return console.error(`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`),{error:`executePermission: plugin '${e.plugin}' not found or has no API on this corsair instance.`,plugin:e.plugin,endpoint:e.endpoint,result:null};let p=ce(a.api,e.endpoint.split("."));if(!p)return console.error(`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`),{endpoint:e.endpoint,plugin:e.plugin,result:null,error:`executePermission: endpoint '${e.endpoint}' not found in plugin '${e.plugin}'.`};await n.permissions.set_executing(e.id);try{let t=typeof e.args=="string"?JSON.parse(e.args):e.args,i=await p(t);return await n.permissions.set_completed(e.id),{plugin:e.plugin,endpoint:e.endpoint,result:i}}catch(t){let i=t instanceof Error?t.message:String(t),u=y(n);return u&&await u.db.updateTable("corsair_permissions").set({status:"failed",error:i,updated_at:new Date}).where("id","=",e.id).execute(),{plugin:e.plugin,endpoint:e.endpoint,result:null,error:i}}}export{_ as AuthMissingError,ie as CorsairClientError,v as CorsairKekMissingError,E as DEFAULT_BODY_STALL_TIMEOUT_MS,L as DEFAULT_MAX_BODY_BYTES,I as PermissionRequiredError,T as ReadonlyForbiddenError,ee as asRecord,Q as collectPluginWebhookMatchers,te as createCorsair,se as createCorsairClient,oe as decodePubSubData,de as executePermission,re as firstString,m as formatDocSchemaShape,V as getHeader,pe as getSchema,ue as getStructuredSchema,ae as listOperations,W as managementHandler,z as matchWebhookPlugin,G as matchWebhookPluginAndTenant,A as processCorsair,O as processWebhook,ne as readBodyRecord,N as registerCorsairRawBodyParser,P as resolveAccountFromWebhookLink,H as resolveBodyStallTimeoutMs,w as resolveConnectLink,F as resolveMaxBodyBytes,b as resolveTenantFromWebhookLink,S as resolveTenantIdFromWebhookLink,R as runReadonly,x as setWebhookTenantLink,k as setupCorsair,U as toAstroHandler,M as toExpressHandler,Z as toExternalId,D as toFastifyHandler,$ as toHonoHandler,B as toNextJsHandler,j as toNodeHandler,K as toNuxtHandler,q as toRemixHandler,Y as toSvelteKitHandler,J as toTanStackHandler,X as toWebHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Qa as a,Ra as b,Sa as c}from"./chunk-
|
|
1
|
+
import{Qa as a,Ra as b,Sa as c}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{a as deriveAck,b as pollOnce,c as startConnectLoop};
|
package/dist/oauth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as g,Q as a,R as b,X as c,Y as d,Z as e,_ as f,aa as h}from"./chunk-
|
|
1
|
+
import{$ as g,Q as a,R as b,X as c,Y as d,Z as e,_ as f,aa as h}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{d as OAuthCallbackError,c as buildOAuthAuthorizeUrl,b as decodeOAuthState,a as encodeOAuthState,e as generateOAuthUrl,f as processOAuthCallback,g as renewSubscriptions,h as startSubscriptionRenewal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{O as a,P as b}from"./chunk-
|
|
1
|
+
import{O as a,P as b}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ba as a,ca as b,da as c,ea as d}from"./chunk-
|
|
1
|
+
import{ba as a,ca as b,da as c,ea as d}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as buildConnectPluginManifest,a as buildConnectPluginManifestFromContext,d as ensureConnectAccountRows,c as ensureConnectAccountRowsFromContext};
|
package/dist/setup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{O as a,P as b}from"./chunk-
|
|
1
|
+
import{O as a,P as b}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
package/dist/tunnel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ia as f,Ja as g,Ka as h,La as i,Ma as j,Na as k,Oa as l,Pa as m,T as b,U as c,V as d,W as e,r as a}from"./chunk-
|
|
1
|
+
import{Ia as f,Ja as g,Ka as h,La as i,Ma as j,Na as k,Oa as l,Pa as m,T as b,U as c,V as d,W as e,r as a}from"./chunk-IXPIBTH2.js";import"./chunk-4OLKWKJG.js";import"./chunk-VOH7OVWP.js";import"./chunk-F2EV3CHK.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{l as applyPermissionDecision,f as executeWorkflowRun,h as isAuthCredentialsBrowserDelivery,k as isByoOAuthBrowserDelivery,j as isManagedBrowserDelivery,i as isPermissionBrowserDelivery,m as processCorsair,c as resolveAccountFromWebhookLink,e as resolveTenantFromWebhookLink,d as resolveTenantIdFromWebhookLink,g as runReadonlyProbe,b as setWebhookTenantLink,a as verifyBrowserDeliveryToken};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsair",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.124",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -84,10 +84,10 @@
|
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
86
|
"@corsair-dev/frpc-darwin-arm64": "0.1.117",
|
|
87
|
-
"@corsair-dev/frpc-darwin-x64": "0.1.117",
|
|
88
87
|
"@corsair-dev/frpc-linux-arm64": "0.1.117",
|
|
89
|
-
"@corsair-dev/frpc-win32-arm64": "0.1.117",
|
|
90
88
|
"@corsair-dev/frpc-linux-x64": "0.1.117",
|
|
89
|
+
"@corsair-dev/frpc-win32-arm64": "0.1.117",
|
|
90
|
+
"@corsair-dev/frpc-darwin-x64": "0.1.117",
|
|
91
91
|
"@corsair-dev/frpc-win32-x64": "0.1.117"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|