corsair 0.1.82 → 0.1.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-delivery-CvBUoA96.d.ts +37 -0
- package/dist/chunk-2LV4I6JX.js +38 -0
- package/dist/core.d.ts +5 -5
- package/dist/core.js +1 -1
- package/dist/hub.d.ts +303 -42
- package/dist/hub.js +1 -1
- package/dist/{index-Cl0-2f8A.d.ts → index-CnnnYiGH.d.ts} +302 -261
- package/dist/index-LpuBJQ1m.d.ts +130 -0
- package/dist/{index-VQ5aPg7o.d.ts → index-SNBBST6f.d.ts} +4 -24
- package/dist/index.d.ts +10 -11
- package/dist/index.js +2 -2
- package/dist/oauth.d.ts +18 -1
- package/dist/oauth.js +1 -1
- package/dist/setup.d.ts +3 -3
- package/dist/setup.js +1 -1
- package/dist/{tenant-links-x_63WNLM.d.ts → tenant-links-_vxzYuKb.d.ts} +2 -2
- package/dist/{tenant-match-utils-CXChw66S.d.ts → tenant-match-utils-CMI2112T.d.ts} +3 -3
- package/dist/tunnel.d.ts +7 -7
- package/dist/tunnel.js +1 -1
- package/dist/{types-CqV508wD.d.ts → types-C2vFipdU.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-SBBVO5OB.js +0 -38
- package/dist/index-t-u4QNP-.d.ts +0 -79
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { B as BrowserDeliveryPayload } from './index-LpuBJQ1m.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Browser (client) delivery — hub redirects the user's browser to the app with `?d=<token>`.
|
|
5
|
+
*
|
|
6
|
+
* Used for localhost / loopback dev where the hub cannot POST to the app's delivery URL.
|
|
7
|
+
* The app verifies the token, applies the payload, then redirects to `hubSuccessUrl`.
|
|
8
|
+
*
|
|
9
|
+
* Payload shape: {@link BrowserDeliveryPayload} in `hub/contracts/tunnel.ts`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Builds the redirect URL the hub sends the user's browser to for client-side delivery.
|
|
14
|
+
*
|
|
15
|
+
* @param deliveryUrl - The app's Corsair delivery endpoint (e.g. `http://localhost:3001/api/corsair`).
|
|
16
|
+
* @param signedToken - Output of {@link signBrowserDeliveryToken}.
|
|
17
|
+
*/
|
|
18
|
+
declare function buildBrowserDeliveryRedirectUrl(deliveryUrl: string, signedToken: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Signs a browser delivery payload for redirect-based delivery (local dev / `source: "client"`).
|
|
21
|
+
*
|
|
22
|
+
* Short TTL (60s) — the token travels in the browser URL and must be consumed quickly.
|
|
23
|
+
*
|
|
24
|
+
* @param payload - Delivery-specific fields; `jti`, `iat`, and `exp` are added automatically.
|
|
25
|
+
* @param signingSecret - Per-project signing secret.
|
|
26
|
+
*/
|
|
27
|
+
declare function signBrowserDeliveryToken(payload: Omit<BrowserDeliveryPayload, 'exp' | 'iat' | 'jti'> & {
|
|
28
|
+
jti?: string;
|
|
29
|
+
}, signingSecret: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Verifies a `?d=` browser delivery token from the app side.
|
|
32
|
+
*
|
|
33
|
+
* @returns Decoded payload, or `null` if invalid or expired.
|
|
34
|
+
*/
|
|
35
|
+
declare function verifyBrowserDeliveryToken(token: string, signingSecret: string): BrowserDeliveryPayload | null;
|
|
36
|
+
|
|
37
|
+
export { buildBrowserDeliveryRedirectUrl as b, signBrowserDeliveryToken as s, verifyBrowserDeliveryToken as v };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import{a as se,b as Xt,c as P,d as F,e as er,f as J,g as N,h as $,i as Xe,j as nr,k as Wn,l as tr,m as rr}from"./chunk-NZS35HPL.js";import{a as Qt}from"./chunk-IGGCNGU2.js";var en=["ahrefs","airtable","amplitude","asana","bitwarden","bluesky","box","cal","calendly","cloudflare","cursor","discord","dodopayments","dropbox","exa","figma","firecrawl","fireflies","github","gitlab","gmail","googlecalendar","googledrive","googlesheets","grafana","hackernews","hubspot","intercom","jira","linear","monday","notion","onedrive","openweathermap","oura","outlook","pagerduty","posthog","razorpay","reddit","resend","sentry","sharepoint","slack","spotify","strava","stripe","tally","tavily","teams","telegram","todoist","trello","twilio","twitter","twitterapiio","typeform","vapi","xquik","youtube","zendesk","zohomail","zoom"],or={ahrefs:"Ahrefs",airtable:"Airtable",amplitude:"Amplitude",asana:"Asana",bitwarden:"Bitwarden",bluesky:"Bluesky",box:"Box",cal:"Cal",calendly:"Calendly",cloudflare:"Cloudflare",cursor:"Cursor",discord:"Discord",dodopayments:"Dodo Payments",dropbox:"Dropbox",exa:"Exa",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googlecalendar:"Google Calendar",googledrive:"Google Drive",googlesheets:"Google Sheets",grafana:"Grafana",hackernews:"Hacker News",hubspot:"HubSpot",intercom:"Intercom",jira:"Jira",linear:"Linear",monday:"Monday",notion:"Notion",onedrive:"OneDrive",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",sentry:"Sentry",sharepoint:"SharePoint",slack:"Slack",spotify:"Spotify",strava:"Strava",stripe:"Stripe",tally:"Tally",tavily:"Tavily",teams:"Teams",telegram:"Telegram",todoist:"Todoist",trello:"Trello",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",typeform:"Typeform",vapi:"Vapi",xquik:"XQuik",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom"};function ye(e){let n=or[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var Ne="https://auth.corsair.dev";var me=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret, deliveryUrl } to createCorsair()."),this.name="HubNotConfiguredError"}};function nn(e){let n=(e.apiUrl?.trim()||Ne).replace(/\/$/,""),t=e.projectApiKey.trim(),r=e.signingSecret.trim(),i=e.deliveryUrl.trim();if(!t||!r||!i)throw new Error("Hub config requires non-empty projectApiKey, signingSecret, and deliveryUrl");return{apiUrl:n,projectApiKey:t,signingSecret:r,deliveryUrl:i,oauthCallbackUrl:e.oauthCallbackUrl?.trim()}}function wo(e){return e.apiUrl.trim().length>0&&e.deliveryUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function H(e){let n=P(e).hub;if(!n||!wo(n))throw new me;return n}function tn(e){return e.oauthCallbackUrl?e.oauthCallbackUrl:`${e.apiUrl.replace(/\/$/,"")}/oauth/callback`}function S(e){return typeof e=="string"&&e.length>0}function rn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!S(n.connectUrl)||!S(n.token)||!S(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};return S(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function on(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!S(n.approvalUrl)||!S(n.token)||!S(n.projectId)||!S(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 sn(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(!S(n.access_token))throw new Error("Hub token refresh returned no access_token");return{access_token:n.access_token,refresh_token:S(n.refresh_token)?n.refresh_token:void 0,expires_in:typeof n.expires_in=="number"?n.expires_in:void 0,scope:S(n.scope)?n.scope:void 0}}function ir(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!S(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 i=r;!S(i.plugin)||typeof i.connected!="boolean"||t.push({plugin:i.plugin,providerName:S(i.providerName)?i.providerName:i.plugin,authKind:i.authKind==="oauth"||i.authKind==="api_key"||i.authKind==="bot_token"?i.authKind:"api_key",connected:i.connected})}return{tenantId:n.tenantId,plugins:t}}function an(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function Co(e){return e.replace(/\/$/,"")}async function To(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 Po(e,n,t){if(n===404&&t)return t;let r=an(e);return r||`Hub API returned HTTP ${n}`}async function xe(e){let n=Co(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`},body:JSON.stringify(e.body)}),r=await To(t);if(!t.ok)throw new Error(Po(r,t.status,e.notFoundMessage));return e.parseResponse(r)}import*as $e from"crypto";function z(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function jn(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 i=r;return n!==void 0&&typeof i.iat=="number"&&Date.now()-i.iat>n?null:i}return null}catch{return null}}function ae(e,n){let t=$e.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var Kn=600*1e3;function cn(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),i=e.slice(t+1),o=$e.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(i,"base64url"),a=Buffer.from(o,"base64url");return s.length!==a.length||!$e.timingSafeEqual(s,a)?null:jn(r,{maxAgeMs:Kn})}var vo=new Set(["localhost","127.0.0.1","[::1]","::1"]);function Le(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:vo.has(n)}catch{return!1}}function Ae(e){return Le(e)?"client":"server"}function Zn(e,n){return e==="client"||Le(n)}var sr=Zn;function Re(e){if(!e.source)return null;let n=Le(e.deliveryUrl);return e.source==="server"&&n?{error:'source "server" cannot be used with a loopback delivery URL \u2014 omit source to auto-detect or use "client"',status:400}:e.oauthMode==="managed"&&e.source==="client"&&!n?{error:'managed OAuth with source "client" requires a loopback delivery URL \u2014 omit source for production server delivery',status:400}:null}import{ZodBoolean as Ao,ZodDate as Ro,ZodEnum as So,ZodNullable as Io,ZodNumber as Eo,ZodObject as _o,ZodOptional as Do,ZodRecord as Oo,ZodString as Mo,ZodType as Ho}from"zod";var xo={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:{}}},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:{}}}},qn=xo;async function cr(e,n){let t=[],r=g=>{t.push(g),console.log(g)},i=g=>{t.push(g),console.warn(g)},o=n?.caller??"script",s=Xt(e);if(!s)throw new Error("setupCorsair: invalid corsair instance");if(!s.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let a=Uo(e,s.plugins,n),c={...s,database:s.database},u=c.database.db;await $o(u,i);let d=await Lo(u,c,a.tenantId,a.provisionAccounts,r);n?.credentials&&Object.keys(n.credentials).length>0&&await Ko(e,a,n.credentials,c,r,i);let l=await qo(d,a,r,o);if(n?.backfill){r("[corsair:setup] Starting backfill...");let g=lr({plugins:s.plugins,database:u,kek:s.kek,multiTenancy:!0}).withTenant(a.tenantId);await Go(g,s.plugins,l,r,i),r("[corsair:setup] Backfill complete.")}return t.join(`
|
|
2
|
+
`)}function Gn(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...N[n][t],...r])}function Bo(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let i=n.find(a=>a.id===t);if(!i)continue;let o=$(i);if(!o)continue;let s=Gn(i,o,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Uo(e,n,t){let r=er(e),i=t?.tenantId?.trim(),o=i!==void 0&&i.length>0;if(r&&t?.backfill&&!o)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(r&&Bo(t?.credentials,n)&&!o)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(o&&!i)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:r,tenantIdProvided:o,tenantId:o?i:"default",provisionAccounts:!r||o}}function ur(e,n){return se(e)?n===0?!0:Object.values(e).every(t=>ur(t,n-1)):!1}function Fo(e){return ur(e,4)}var No={...tr};function un(e){if(e instanceof _o){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Ho?un(r):"unknown";return n}return e instanceof Io?`${un(e.unwrap())} | null`:e instanceof Do?`${un(e.unwrap())} | undefined`:e instanceof So?e.options.join(" | "):e instanceof Mo?"string":e instanceof Eo?"number":e instanceof Ao?"boolean":e instanceof Ro?"date":e instanceof Oo?"jsonb":"unknown"}async function $o(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(i=>i.name));for(let[i,o]of Object.entries(No))r.has(i)||n(`[corsair:setup] Table "${i}" does not exist. Run your database migrations before calling setupCorsair.
|
|
3
|
+
Schema: ${JSON.stringify(un(o),null,2)}`)}async function Lo(e,n,t,r,i){let o=new Date,s=new Map;for(let a of n.plugins){let c=a.id,u=$(a),d=await e.selectFrom("corsair_integrations").selectAll().where("name","=",c).executeTakeFirst();if(!d){let y=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:y,name:c,config:{},created_at:o,updated_at:o}).execute(),d=await e.selectFrom("corsair_integrations").selectAll().where("id","=",y).executeTakeFirst(),i(`[corsair:setup] Created integration: ${c}`)}let l=u?a.authConfig?.[u]?.integration??[]:[],g=u?a.authConfig?.[u]?.account??[]:[],f=u&&d?O({authType:u,integrationName:c,kek:n.kek,database:n.database,extraIntegrationFields:l}):void 0;if(d&&!d.dek&&f&&(await f.issue_new_dek(),i(`[corsair:setup] Issued integration DEK: ${c}`)),!d||!u||!f)continue;let p;if(r){let y=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",d.id).executeTakeFirst();if(!y){let m=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:m,tenant_id:t,integration_id:d.id,config:{},created_at:o,updated_at:o}).execute(),y=await e.selectFrom("corsair_accounts").selectAll().where("id","=",m).executeTakeFirst(),i(`[corsair:setup] Created account: ${c}`)}p=y&&I({authType:u,integrationName:c,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:g}),y&&p&&!y.dek&&(await p.issue_new_dek(),i(`[corsair:setup] Issued account DEK: ${c}`))}s.set(c,{pluginId:c,authType:u,integration:f,account:p,integrationFields:[...N[u].integration,...l],accountFields:r?[...N[u].account,...g]:[]})}return s}function Wo(e){if(!se(e))return;let n=e.keys;return se(n)?n:void 0}function jo(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Ko(e,n,t,r,i,o){let s=Wo(e),a=n.provisionAccounts?jo(e,n.tenantId):void 0;for(let[c,u]of Object.entries(t)){let d=r.plugins.find(h=>h.id===c);if(!d){o(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let l=$(d);if(!l){o(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let g=Gn(d,l,"integration"),f=Gn(d,l,"account"),p=s?.[c],y=a?.[c],m=se(y)?y.keys:void 0;for(let[h,C]of Object.entries(u))if(C){if(g.has(h)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${h}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let b=J(p,`set_${h}`);if(!b){o(`[corsair:setup] Cannot set integration field '${h}' for '${c}'.`);continue}await b(C),i(`[corsair:setup] Set ${c} integration.${h}`);continue}if(f.has(h)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${h}' on a multi-tenant instance`);let b=J(m,`set_${h}`);if(!b){o(`[corsair:setup] Cannot set account field '${h}' for '${c}'.`);continue}await b(C),i(`[corsair:setup] Set ${c} account.${h} (tenant=${n.tenantId})`);continue}o(`[corsair:setup] Unknown credential field '${h}' for plugin '${c}'.`)}}}var ar=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Zo(e,n,t,r,i,o,s,a,c){let u=[],d=[];for(let g of i){if(ar.has(g))continue;let f=J(t,`get_${g}`);if(!f)continue;let p=null;try{let y=await f();p=typeof y=="string"?y:null}catch{}p||u.push(g)}if(r&&o.length>0)for(let g of o){if(ar.has(g))continue;let f=J(r,`get_${g}`);if(!f)continue;let p=null;try{let y=await f();p=typeof y=="string"?y:null}catch{}p||d.push(g)}let l=u.length===0&&d.length===0;if(l)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else{let g=[...u,...d];if(c==="cli"){let f=g.map(p=>`${p}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
4
|
+
corsair setup --${e} ${f}`)}else{let f=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let p of u)f.push(` await corsair.keys.${e}.set_${p}(value)`);for(let p of d){let y=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;f.push(` await ${y}.keys.set_${p}(value)`)}a(f.join(`
|
|
5
|
+
`))}}return l}async function qo(e,n,t,r){let i=new Set;for(let o of e.values())await Zo(o.pluginId,o.authType,o.integration,o.account,o.integrationFields,o.accountFields,n,t,r)&&i.add(o.pluginId);return i}async function Go(e,n,t,r,i){if(!Fo(qn)){i("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let o=qn,s=new Set(n.map(a=>a.id));for(let[a,c]of Object.entries(o)){if(!s.has(a))continue;if(!t.has(a)){r(`[corsair:setup] Skipping backfill for '${a}' \u2014 auth not configured.`);continue}let u=se(e)?e[a]:void 0,d=se(u)?u.api:void 0;if(d)for(let[l,g]of Object.entries(c))for(let[f,p]of Object.entries(g)){r(`[corsair:setup] Backfilling ${a} \u203A ${l}.${f}...`);try{let y=se(d)?d[l]:void 0;await J(y,f)?.(p)}catch(y){i(`[corsair:setup] ${a} \u203A ${l}.${f} failed: `+(y instanceof Error?y.message:String(y)))}}}}async function Se(e,n){if(!P(e).database)throw new Error("A database must be configured to provision Corsair for connect");await cr(e,{tenantId:n})}var Jo=new Set(["webhook_signature","expires_at","scope"]);function zo(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Vo(e){return e==="oauth_2"||e==="managed"?["access_token"]:e==="api_key"?["api_key"]:e==="bot_token"?["bot_token"]:[]}async function Yo(e,n,t,r){let i=Vo(t);if(i.length===0)return!0;let s=(typeof e.withTenant=="function"?e.withTenant(r):e)[n.id],a=s&&typeof s=="object"&&"keys"in s?s.keys:null;if(!a)return!1;for(let c of i){if((t==="oauth_2"||t==="managed")&&c==="refresh_token")continue;let u=J(a,`get_${c}`);if(!u)continue;let d=null;try{let l=await u();d=typeof l=="string"?l:null}catch{d=null}if(!d)return!1}return!0}function Qo(e,n){return e==="oauth_2"||e==="managed"?[]:n.filter(t=>!Jo.has(t))}async function dr(e,n,t={}){let r=P(e),i=H(e),o=tn(i),s=[],a=t.pluginIds?new Set(t.pluginIds):null;for(let c of r.plugins){if(a&&!a.has(c.id))continue;let u=$(c);if(!u)continue;let d=zo(u),l=t.providerNameOverrides?.[c.id]??ye(c.id),g=await Yo(e,c,u,n),f=Xe(c,u),p={plugin:c.id,providerName:l,authKind:d,alreadyConfigured:g};if(d==="oauth"){let m=t.oauthModeOverrides?.[c.id]??(u==="managed"?"managed":"byo");if(p.oauthMode=m,!t.skipOAuthUrlGeneration)if(m==="managed")p.state=ae(z(c.id,n),r.kek);else try{let h=await Jn(e,c.id,{tenantId:n,redirectUri:o});p.oauthUrl=h.url,p.state=h.state}catch(h){p.setupError=h instanceof Error?h.message:`Could not prepare OAuth for ${c.id}`}}else{let y=Qo(u,f);y.length>0&&(p.credentialFields=y)}s.push(p)}return s}function pr(e,n){let t=H(e);if(n){let r=Re({source:n,deliveryUrl:t.deliveryUrl});if(r)throw new Error(r.error);return n}return Ae(t.deliveryUrl)}async function gr(e,n){await Se(e,n)}async function ln(e,n){let t=H(e);await gr(e,n.tenantId);let r=n.plugin?[n.plugin]:void 0,i=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,o=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,s=await dr(e,n.tenantId,{pluginIds:r,oauthModeOverrides:i,providerNameOverrides:o});if(s.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");let a=pr(e,n.source);return xe({hub:t,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:{tenantId:n.tenantId,deliveryUrl:t.deliveryUrl,source:a,plugins:s},parseResponse:rn})}import{createCipheriv as fr,createDecipheriv as yr,randomBytes as dn,scrypt as Xo}from"crypto";import{promisify as ei}from"util";var mr=ei(Xo),pn="aes-256-gcm",hr=12,gn=16,ni=16,We=32;function ee(){return dn(We).toString("base64")}async function ne(e,n){let t=dn(ni),r=await mr(n,t,We),i=dn(hr),o=fr(pn,r,i,{authTagLength:gn}),s=Buffer.concat([o.update(e,"utf8"),o.final()]),a=o.getAuthTag();return[t.toString("base64"),i.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function L(e,n){let[t,r,i,o]=e.split(":");if(!t||!r||!i||!o)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(i,"base64"),u=Buffer.from(o,"base64"),d=await mr(n,s,We),l=yr(pn,d,a,{authTagLength:gn});return l.setAuthTag(c),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function zn(e,n){let t=Buffer.from(n,"base64"),r=dn(hr),i=fr(pn,t,r,{authTagLength:gn}),o=Buffer.concat([i.update(e,"utf8"),i.final()]),s=i.getAuthTag();return[r.toString("base64"),s.toString("base64"),o.toString("base64")].join(":")}function je(e,n){let[t,r,i]=e.split(":");if(!t||!r||!i)throw new Error("Invalid encrypted data format");let o=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(i,"base64"),u=yr(pn,o,s,{authTagLength:gn});return u.setAuthTag(a),Buffer.concat([u.update(c),u.final()]).toString("utf8")}function ce(e,n){let t={};for(let[r,i]of Object.entries(e))t[r]=zn(i,n);return t}function te(e,n){let t={};for(let[r,i]of Object.entries(e))t[r]=je(i,n);return t}function Ke(e,n,t){let r=te(e,n);return ce(r,t)}function kr(e,n,t){let r={};for(let i of t)r[`get_${i}`]=async()=>(await e())[i]??null,r[`set_${i}`]=async o=>{let s=[null,void 0,""].includes(o)?null:o;await n({[i]:s})};return r}var Vn=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function O(e){let{authType:n,integrationName:t,kek:r,database:i,extraIntegrationFields:o=[]}=e,s=[...N[n].integration,...o],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let p=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!p)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:p.id,config:Vn(p.config),dek:p.dek??null},a},updateIntegration:async p=>{let y=await c.getIntegration();await i.db.updateTable("corsair_integrations").set({...p.config!==void 0?{config:p.config}:{},...p.dek!==void 0?{dek:p.dek}:{},updated_at:new Date}).where("id","=",y.id).execute(),a=null}},u=null,d=async()=>{if(u)return u;let p=await c.getIntegration();if(!p.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return u=await L(p.dek,r),u},l=async()=>{let p=await c.getIntegration(),y=await d(),m=p.config;return!m||Object.keys(m).length===0?{}:te(m,y)};return{get_dek:d,issue_new_dek:async()=>{let p=await c.getIntegration(),y=ee(),m={};if(p.dek){let C=await L(p.dek,r),b=p.config;b&&Object.keys(b).length>0&&(m=Ke(b,C,y))}let h=await ne(y,r);return await c.updateIntegration({config:m,dek:h}),u=y,y},...kr(l,async p=>{let y=await d(),m;try{m=await l()}catch(b){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,b),m={}}let h={...m};for(let[b,k]of Object.entries(p))k===null?delete h[b]:h[b]=k;let C=ce(h,y);await c.updateIntegration({config:C})},s)}}function I(e){let{authType:n,integrationName:t,tenantId:r,kek:i,database:o,extraAccountFields:s=[]}=e,a=[...N[n].account,...s],c=null,u=null,d=async()=>{if(u)return u;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 u={id:k.id,config:Vn(k.config),dek:k.dek??null},u},l={kek:i,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(c)return c;let k=await d(),w=await o.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",k.id).executeTakeFirst();if(!w)throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`);return c={id:w.id,config:Vn(w.config),dek:w.dek??null},c},updateAccount:async k=>{let w=await l.getAccount();await o.db.updateTable("corsair_accounts").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",w.id).execute(),c=null}},g=null,f=null,p=async()=>{if(g)return g;let k=await l.getAccount();if(!k.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await L(k.dek,i),g},y=async()=>{if(f)return f;let k=await l.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await L(k.dek,i),f},m=async()=>{let k=await l.getAccount(),w=await p(),T=k.config;return!T||Object.keys(T).length===0?{}:te(T,w)},h=async()=>{let k=await l.getIntegration(),w=await y(),T=k.config;return!T||Object.keys(T).length===0?{}:te(T,w)},b={get_dek:p,issue_new_dek:async()=>{let k=await l.getAccount(),w=ee(),T={};if(k.dek){let _=await L(k.dek,i),D=k.config;D&&Object.keys(D).length>0&&(T=Ke(D,_,w))}let E=await ne(w,i);return await l.updateAccount({config:T,dek:E}),g=w,w},...kr(m,async k=>{let w=await p(),T;try{T=await m()}catch(D){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,D),T={}}let E={...T};for(let[D,x]of Object.entries(k))x===null?delete E[D]:E[D]=x;let _=ce(E,w);await l.updateAccount({config:_})},a)};return n==="oauth_2"&&(b.get_integration_credentials=async()=>{let k=await h();return{client_id:k.client_id||null,client_secret:k.client_secret||null,redirect_url:k.redirect_url??null}}),b}async function br(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 i=ee(),o=await ne(i,t);return await e.db.updateTable("corsair_integrations").set({dek:o,updated_at:new Date}).where("id","=",r.id).execute(),i}async function wr(e,n,t,r){let i=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!i)throw new Error(`Integration "${n}" not found.`);let o=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",i.id).executeTakeFirst();if(!o)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=ee(),a=await ne(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",o.id).execute(),s}function Ie(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}import*as Cr from"querystring";function Ee(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:i}=e,o={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:i};return`${n.authUrl}?${Cr.stringify(o)}`}var W=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function ti(e){let n=e.oauthConfig;if(!n)throw new W("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Yn(e,n){let t=P(e,()=>new W("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new W("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new W("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let i=cn(n,t.kek);if(!i)throw new W("invalid_state","Invalid or tampered state parameter");let{plugin:o,tenantId:s}=i,a=F(t,o,g=>new W("plugin_not_found",g)),c=ti(a),d=await O({authType:"oauth_2",integrationName:o,kek:t.kek,database:t.database}).get_client_id();if(!d)throw new W("client_id_not_configured",`client_id not configured for '${o}'`);let l=Ee({oauthConfig:c,clientId:d,redirectUri:r,state:n});return{plugin:o,tenantId:s,providerName:c.providerName,oauthUrl:l,state:n}}import{randomBytes as oi}from"crypto";import{v4 as ii}from"uuid";async function fn(e,n){return xe({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:{permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,deliveryUrl:e.deliveryUrl,expiresAt:n.expiresAt},parseResponse:on})}function yn(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var Qn="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 et(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Tr(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function Xn(e){return yn(e)}async function nt(e,n){if(et(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Tr(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await fn(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:ri(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ri(e){try{return JSON.parse(e)}catch{return e}}async function mn(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await nt(e,n);return{...n,approvalUrl:r}}async function tt(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:i,permissionToken:o,plugin:s,endpoint:a,args:c,tenantId:u,expiresAt:d,operationPath:l}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:o,id:i,plugin:s,endpoint:a,args:c});let f=await nt({manual:t,hub:r},{id:i,token:o,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:u,expires_at:d});return et(t)?f?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:f}):Xn(f):Qn:r?f?Xn(f):`Action '${l}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:Qn}var si={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 ai(e,n,t){return t!==void 0?t:si[n][e]}function rt(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let i=parseInt(r[1],10);switch(r[2]){case"d":t+=i*864e5;break;case"h":t+=i*36e5;break;case"m":t+=i*6e4;break;case"s":t+=i*1e3;break}}return t>0?t:600*1e3}function vr(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 Pr(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let i=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!i)return{result:"blocked",reason:"pending"};if(i.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(i.status==="denied")return{result:"blocked",reason:"denied"};if(i.status==="expired"||i.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(o=>setTimeout(o,500))}return{result:"blocked",reason:"timeout"}}async function xr(e){let n=ai(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}'.`,`
|
|
6
|
+
Action: ${r}`,`
|
|
7
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let i=JSON.stringify(e.args),o=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","=",i).where("tenant_id","=",s).where("expires_at",">",o).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let p=e.db,y=a.id;return{result:"allow",onComplete:async()=>{await p.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",y).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
8
|
+
Action: ${r}`,`
|
|
9
|
+
Permission ID: ${a.id}`,`
|
|
10
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Pr(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let c=ii(),u=oi(32).toString("hex"),d=e.timeoutMs??600*1e3,l=new Date(Date.now()+d).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:c,created_at:new Date,updated_at:new Date,token:u,plugin:e.pluginId,endpoint:e.endpointPath,args:i,tenant_id:s,status:"pending",expires_at:l}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
11
|
+
Action: ${r}`,`
|
|
12
|
+
Permission ID: ${c}`,`
|
|
13
|
+
Permission token: ${u}`,`
|
|
14
|
+
Expires at: ${l}`,`
|
|
15
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Pr(e.db,c,d):{result:"blocked",reason:"pending",id:c,token:u,expiresAt:l}}var v=class extends Error{status;code;extra;constructor(n,t,r,i={}){super(r??t),this.name="ManagementApiError",this.status=n,this.code=t,this.extra=i}};function A(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function Ar(e){let n={error:e.code,message:e.message,...e.extra};return A(e.status,n)}function ue(e){return new v(404,"not_found",e)}function V(e,n={}){return new v(400,"bad_request",e,n)}function Rr(e,n){return F(e,n,t=>ue(t))}async function ot(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=O({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),i=N[t].integration,o=r,s;try{s=await Promise.all(i.map(u=>o[`get_${u}`]()))}catch{s=i.map(()=>null)}let a=i.filter((u,d)=>s[d]==null),c;return t==="oauth_2"?c=!a.includes("client_id")&&!a.includes("client_secret"):c=a.length===0,{configured:c,missingFields:a}}async function Sr(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:i,missingFields:o}=await ot(e,n);return{id:e.id,authType:t,configured:i,missingFields:o,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function hn(){return{ok:!0}}async function kn(e){return Promise.all(e.plugins.map(n=>Sr(n,e)))}async function bn(e,n){let t=Rr(e,n);return Sr(t,e)}async function Ir(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 Er(e,n){let t=await Ir(e,n),r=t.filter(i=>i.hasCredentials).map(i=>i.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function wn(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 i=r.tenant_id;if(!i)continue;let o=n.get(i);o||(o={id:i,accounts:[],connectedPlugins:[]},n.set(i,o));let s=!!r.dek;o.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&o.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function Cn(e,n){if(!n)throw V("Tenant id must be a non-empty string");return Er(e,n)}async function Tn(e,n){let t=n?.id?.trim();if(!t)throw V("Tenant id is required",{missingFields:["id"]});return Er(e,t)}async function _e(e,n){let t=n?.trim()||"default",r={},i=e.database?await Ir(e,t):[],o=new Map(i.map(s=>[s.integrationName,s]));for(let s of e.plugins){if(!(await ot(s,e)).configured){r[s.id]="missing_credentials";continue}let c=o.get(s.id),u;c&&c.hasCredentials?u="connected":u="not_connected",r[s.id]=u}return r}async function it(e,n){if(!e.database)throw ue(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw ue(`Permission '${n}' not found`);return mn(e,t)}function ci(e){if(!e.oauthConfig)throw V(`Plugin '${e.id}' has no oauthConfig`)}function ui(e){if(!e.manual)throw new v(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function st(e){let n=ui(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new v(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 li(e){let n=!!e.hub,t=Ie(e.manual);if(!n&&!t)throw new v(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function _r(e){if(!e.database||!e.kek)throw new v(500,"database_not_configured","A database and kek are required to issue connect links.")}async function di(e,n){let t=n?.plugin?.trim();if(!t)throw V("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",i=Rr(e,t);ci(i);let o=st(e);_r(e);let s=await ot(i,e);if(!s.configured)throw new v(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=ae(z(t,r),e.kek),c;try{c=new URL(o.baseUrl)}catch{throw new v(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return c.searchParams.set("state",a),{connectUrl:c.toString(),expiresAt:new Date(Date.now()+Kn).toISOString()}}async function pi(e,n,t){_r(n);let r=t.tenantId?.trim()||"default",i=H(e);if(t.source){let u=Re({source:t.source,deliveryUrl:i.deliveryUrl,oauthMode:t.oauthMode});if(u)throw V(u.error)}let o={tenantId:r,source:t.source??Ae(i.deliveryUrl),oauthMode:t.oauthMode},s=t.plugin?.trim();s&&(o.plugin=s);let a=t.providerName?.trim();a&&(o.providerName=a);let c=await ln(e,o);return{connectUrl:c.connectUrl,expiresAt:c.expiresAt}}async function Pn(e,n,t){return li(n),n.hub?pi(e,n,t):di(n,t)}async function vn(e,n,t){if(n.hub&&!Ie(n.manual))throw new v(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw V("state is required",{missingFields:["state"]});st(n);try{return await Yn(e,r)}catch(i){if(i instanceof W)switch(i.code){case"invalid_state":throw V("Invalid or expired state");case"client_id_not_configured":throw new v(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new v(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function xn(e,n,t){if(n.hub&&!Ie(n.manual))throw new v(400,"hub_mode","oauthCallback is not used with hub config. Hub delivers tokens to your deliveryUrl.");let r=t?.code?.trim(),i=t?.state?.trim(),o=[];if(r||o.push("code"),i||o.push("state"),o.length)throw V("Missing required fields",{missingFields:o});let s=st(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:i,redirectUri:s.redirectUri})}catch(c){if(c instanceof Error&&c.name==="OAuthCallbackError")switch(c.code){case"invalid_state":throw V("Invalid or expired state");case"credentials_not_configured":throw new v(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new v(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function at(e,n){if(!e.database)throw ue("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw ue("Permission not found");return mn(e,t)}async function Dr(e,n){return"id"in n?it(e,n.id):at(e,n.token)}function gi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function fi(e,n){return n&&!n.has(e.id)?!1:$(e)!==null}async function De(e,n,t={}){let r=P(e),i=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,s=await _e(r,i),a=r.plugins.filter(c=>fi(c,o)).map(c=>{let u=$(c),d=s[c.id]??"not_connected";return{plugin:c.id,providerName:ye(c.id),authKind:gi(u),connected:d==="connected"}});return{tenantId:i,plugins:a}}var le=6e4,he=3e5;var Y=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function An(e,n){let t=P(e,()=>new Y("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new Y("no_database","Database not configured");let r=F(t,n.plugin,d=>new Y("plugin_not_found",d)),i=$(r);if(!i)throw new Y("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(i==="oauth_2"||i==="managed")throw new Y("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await Se(e,n.tenantId);let o=new Set(Xe(r,i)),a=r.authConfig?.[i]?.account??[],c=I({authType:i,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),u=0;for(let[d,l]of Object.entries(n.credentials)){if(!l.trim())continue;if(!o.has(d))throw new Y("invalid_credentials",`Unknown credential field '${d}' for plugin '${n.plugin}'`);let g=J(c,`set_${d}`);if(!g)throw new Y("invalid_credentials",`Cannot set credential field '${d}' for plugin '${n.plugin}'`);await g(l.trim()),u+=1}if(u===0)throw new Y("invalid_credentials","Provide at least one credential field to save");return{plugin:n.plugin,tenantId:n.tenantId}}var Rn=new Map;function yi(e){for(let[n,t]of Rn)t<=e&&Rn.delete(n)}function Sn(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};let r=Date.now();return yi(r),Rn.has(t)?{ok:!1,error:"Delivery request already consumed"}:(Rn.set(t,r+n),{ok:!0})}async function In(e,n,t){for(let r of e){if(r.id!==n)continue;let i=r.oauthWebhookTenantLinkResolver;return i?i(t):null}return null}var Or=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function mi(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 hi(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 L(n.dek,e.kek),r=Or(n.config),i={};Object.keys(r).length>0&&(i=te(r,t)),i[e.link.linkType]=e.link.externalId;let o=ce(i,t);await e.database.db.updateTable("corsair_accounts").set({config:o,updated_at:new Date}).where("id","=",n.id).execute()}async function Oe(e){let{database:n,kek:t,pluginId:r,tenantId:i,link:o,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await mi({database:n,pluginId:r,tenantId:i}),u=!1;if(s){let d=I({authType:s,integrationName:r,tenantId:i,kek:t,database:n,extraAccountFields:a}),l=`set_${o.linkType}`,g=d[l];typeof g=="function"&&(await g(o.externalId),u=!0)}u||await hi({database:n,kek:t,accountId:c,link:o})}async function ct(e){let{database:n,kek:t,pluginId:r,linkType:i,externalId:o}=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 c=await L(a.dek,t),d=Or(a.config)[i];if(!d)continue;if(je(d,c)===o)return a}catch{continue}return null}async function En(e){return(await ct(e))?.tenant_id??null}async function Mr(e){return En({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}var de=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function Me(e,n){let{plugin:t,tenantId:r,accessToken:i,refreshToken:o,expiresIn:s,scope:a}=n;if(!i.trim())throw new de("no_access_token","Managed OAuth delivery missing access_token");let c=P(e,()=>new de("invalid_corsair_instance","Invalid corsair instance"));if(!c.database)throw new de("no_database","No database configured on corsair instance");let u=F(c,t,l=>new de("plugin_not_found",l));await Se(e,r);let d=I({authType:"managed",integrationName:t,tenantId:r,kek:c.kek,database:c.database});await d.set_access_token(i),o&&await d.set_refresh_token(o),s&&await d.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await d.set_scope(a);try{let l=await In(c.plugins,t,{access_token:i,refresh_token:o,scope:a});if(l)try{let g=u.authConfig?.managed?.account??[];await Oe({database:c.database,kek:c.kek,pluginId:t,tenantId:r,link:l,authType:"managed",extraAccountFields:g})}catch(g){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,g)}}catch(l){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,l)}return{plugin:t,tenantId:r}}function ki(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Hr(e,n,t=[]){for(let[r,i]of Object.entries(e))if(ki(i)){if(i.match(n))return{webhook:i,path:[...t,r]}}else if(i&&typeof i=="object"){let o=Hr(i,n,[...t,r]);if(o)return o}return null}function bi(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function wi(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 Br(e,n,t,r){let i=bi(n),o=typeof t=="string"?JSON.parse(t):t;(!o||typeof o=="object"&&Object.keys(o).length===0)&&i["x-goog-resource-uri"]&&(o=wi(i)||o);let a={headers:i,body:o,...r?{query:r}:{}},c=r?.tenantId||"default",u=e.withTenant?e.withTenant(c):e,d=en;for(let l of d){let g=u[l];if(!g||!g.webhooks||g.pluginWebhookMatcher&&!g.pluginWebhookMatcher(a))continue;let f=Hr(g.webhooks,a);if(!f)continue;let p=f.path.join("."),y={payload:o,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{}};try{let m=await f.webhook.handler(y),h=!!Object.keys(m.returnToSender||{})?.length;return{plugin:l,action:p,body:o,response:h?{...m?.returnToSender,success:!0}:{success:!0},...m.responseHeaders&&{responseHeaders:m.responseHeaders}}}catch(m){return console.error(`Error executing webhook handler for ${l}.${p}:`,m),{plugin:l,action:p,body:o,response:{success:!1,error:m instanceof Error?m.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHmac as ut,randomUUID as Ci,timingSafeEqual as Ur}from"crypto";function Fr(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function _n(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=ut("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":Ci()}}}function lt(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Fr(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>3e5)return!1;let o=ut("sha256",n).update(e.body).digest("hex");try{return Ur(Buffer.from(o,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function He(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Fr(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)>3e5)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let o=ut("sha256",n).update(e.body).digest("hex");try{if(!Ur(Buffer.from(o,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function dt(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function pt(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function gt(e){return e.status===0?`Could not reach delivery URL (${e.deliveryUrl}): ${e.ack.error??e.body}`:e.ack.error??e.body??`HTTP ${e.status}`}async function ft(e){let{body:n,headers:t}=_n(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n}),i=await r.text();return{ok:r.ok,status:r.status,body:i}}catch(r){return{ok:!1,status:0,body:r instanceof Error?r.message:"Delivery request failed"}}}import{randomBytes as xi}from"crypto";import{createHmac as Ti,randomBytes as Pi,timingSafeEqual as vi}from"crypto";function re(){return Pi(16).toString("base64url")}function Ze(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ti("sha256",t).update(e).digest("base64url")}function Q(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[i,o]=r;if(!i||!o)return null;let s=Ze(i,t);try{if(!vi(Buffer.from(o,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(i,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function Dn(e,n,t){let r=Math.floor(Date.now()/1e3),i={...e,iat:r,exp:t},o=Buffer.from(JSON.stringify(i)).toString("base64url"),s=Ze(o,n);return`${o}.${s}`}function qe(e,n,t){let r=Math.floor(Date.now()/1e3);return Dn(e,n,r+Math.floor(t/1e3))}function ke(e){return decodeURIComponent(e)}function yt(e){return encodeURIComponent(e)}function Nr(e){let n=e.trim();return n.length>0?n:null}function On(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Mn(e,n){if(!Nr(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??xi(16).toString("base64url"),iat:t,exp:t+Math.floor(6e4/1e3)},i=Buffer.from(JSON.stringify(r)).toString("base64url"),o=Ze(i,n);return`${i}.${o}`}function pe(e,n){return Nr(n)?Q(e,n):null}function be(e){return e.deliveryMode==="connect.status"}function we(e){return e.deliveryMode==="auth.credentials"}function Ge(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Je(e){return e.deliveryMode==="oauth.tokens"}function Hn(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!be(e)&&!we(e)&&!Ge(e)&&!Je(e)}function mt(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 Ai(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 En({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function Ri(e,n,t){let r=await Ai(e,n,t),i={...t.query??{},...r?{tenantId:r}:{}},o=await Br(e,t.headers,t.body,i);if(!o.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(o.response&&o.response.success===!1)return{status:"failed",retryable:!1,error:typeof o.response.error=="string"?o.response.error:"Webhook handler failed"};let s=o.response?.returnToSender,a=s&&typeof s=="object"&&typeof s.validationToken=="string"&&Object.keys(s).length===1?s.validationToken:s||(o.response?.data??o.response);return{status:"ok",webhookResponse:{status:o.response?.statusCode??200,body:a,headers:o.responseHeaders}}}async function Si(e,n){return await ze(e,n),{status:"ok"}}async function Ii(e,n){return await Me(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope}),{status:"ok"}}async function kt(e,n,t){let r=await ht(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function ht(e,n,t){let r=P(e),i=n.token?.trim();if(!i)return{status:"failed",retryable:!1,error:"Permission token is required"};if(!r.database)return{status:"failed",retryable:!1,error:"Database not configured"};let o=new Date().toISOString(),s=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",i).executeTakeFirst();return s?s.status!=="pending"?{status:"ok"}:s.expires_at<o?(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 Ei(e,n){try{return await An(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function _i(e,n){let t=n.tenantId?.trim()||"default";try{return{status:"ok",webhookResponse:{status:200,body:await De(e,t,{pluginIds:n.plugins})}}}catch(r){return{status:"failed",retryable:!1,error:r instanceof Error?r.message:"Connect status introspection failed"}}}async function bt(e,n,t={}){let r=P(e),i=mt(n.headers,"x-corsair-signature"),o=mt(n.headers,"x-corsair-timestamp"),s=mt(n.headers,"x-corsair-nonce");if(t.signingSecret?.trim()){let c=He({body:n.body,signatureHeader:i,timestampHeader:o,signingSecret:t.signingSecret});if(!c.ok)return{status:"failed",retryable:!1,error:c.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let u=Sn(`nonce:${s.trim()}`,3e5);if(!u.ok)return{status:"failed",retryable:!1,error:u.error}}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let a;try{a=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}switch(a.type){case"webhook":return Ri(e,r,a.payload);case"oauth.callback":return Si(e,a.payload);case"oauth.tokens":return Ii(e,a.payload);case"permission.approve":return ht(e,a.payload,"approved");case"permission.deny":return ht(e,a.payload,"denied");case"auth.credentials":return Ei(e,a.payload);case"connect.status":return _i(e,a.payload);default:return{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${a.type}`}}}var Di="corsair:client-bridge";function $r(e){let n=JSON.stringify({type:Di,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(e.hubOrigin);return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
16
|
+
(function () {
|
|
17
|
+
var message = ${n};
|
|
18
|
+
var targetOrigin = ${t};
|
|
19
|
+
if (window.parent && window.parent !== window) {
|
|
20
|
+
window.parent.postMessage(message, targetOrigin);
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
</script></body></html>`}var Oi=[".corsair.dev"];function Mi(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function Hi(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Mi(n)?!0:Oi.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Lr(e){return!e||!Hi(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 Wr(e,n){if(!n)return e;let t=new Headers(e.headers);for(let[r,i]of Object.entries(n))t.set(r,i);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function Bn(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 wt(e,n){let t=H(e),i=new URL(n).searchParams.get("d");if(!i)return{type:"json",status:200,body:{status:"ok",message:"Corsair tunnel endpoint is active",timestamp:new Date().toISOString()}};let o=pe(i,t.signingSecret);if(!o)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=Sn(`browser:${o.jti}`,6e4);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(be(o)){if(!o.hubSuccessUrl)return{type:"json",status:400,body:{error:"Connect status delivery missing hubSuccessUrl"}};let a=o.tenantId?.trim()||"default",c=await De(e,a,{pluginIds:o.statusPlugins});return{type:"redirect",url:Bn(o.hubSuccessUrl,{status:c})}}if(we(o))return o.hubSuccessUrl?o.credentials?(await An(e,{plugin:o.plugin,tenantId:o.tenantId,credentials:o.credentials}),{type:"redirect",url:Bn(o.hubSuccessUrl,{connectedPlugin:o.plugin})}):{type:"redirect",url:Bn(o.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(Ge(o)){if(!o.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await kt(e,o.permissionToken,o.deliveryMode==="permission.approve"?"approved":"denied")}else if(Je(o)){if(!o.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await Me(e,{plugin:o.plugin,tenantId:o.tenantId,accessToken:o.accessToken,refreshToken:o.refreshToken,expiresIn:o.expiresIn,scope:o.scope})}else{if(!Hn(o)||!o.code||!o.state||!o.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await ze(e,{code:o.code,state:o.state,redirectUri:o.redirectUri})}}catch(a){let c=a instanceof Error?a.message:"Hub delivery failed";return(be(o)||we(o))&&o.hubSuccessUrl?{type:"redirect",url:Bn(o.hubSuccessUrl,{error:c})}:(be(o)||we(o))&&o.hubOrigin&&o.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:$r({hubOrigin:o.hubOrigin,requestId:o.requestId,ok:!1,error:c})}:{type:"json",status:400,body:{error:c}}}return{type:"redirect",url:o.hubSuccessUrl}}async function Ct(e,n){let t=H(e),r=await bt(e,n,{signingSecret:t.signingSecret});if(r.status!=="ok")return{type:"json",status:r.retryable===!1?400:502,body:{error:r.error??"Tunnel processing failed"}};let i=r.webhookResponse;if(!i)return{type:"json",status:200,body:{status:"ok"}};let o=i.status??200,s=i.headers;return i.body&&typeof i.body=="object"&&!(i.body instanceof ArrayBuffer)?{type:"json",status:o,body:i.body,headers:s}:{type:"text",status:o,body:typeof i.body=="string"?i.body:i.body?JSON.stringify(i.body):null,headers:s}}function Tt(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 Pt(e,n){return n.method==="GET"?wt(e,n.url):Ct(e,{headers:n.headers,body:n.body??""})}async function vt(e,n){try{let t=await Pt(e,n);return Tt(t)}catch(t){if(t instanceof me)return Response.json({error:t.message},{status:503});throw t}}async function Ve(e,n){let t=n.method.toUpperCase(),r=Lr(n.headers.get("origin"));if(t==="OPTIONS")return r?new Response(null,{status:204,headers:r}):Response.json({error:"Method not allowed"},{status:405});if(t!=="GET"&&t!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await vt(e,{method:t,url:n.url,headers:n.headers,body:t==="POST"?await n.text():void 0});return Wr(i,r)}var oe=class extends Error{pluginId;authType;constructor(n,t,r){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t}};var Bi=300;async function xt(e,n){let{keys:t,hub:r,plugin:i,tenantId:o}=e,s=n?.forceRefresh??!1,[a,c,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!a&&!u)throw new oe(i,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&a&&c&&Number(c)>d+Bi)return{accessToken:a,expiresAt:Number(c),refreshed:!1};if(!u&&a&&!s)return{accessToken:a,expiresAt:c?Number(c):d+3600,refreshed:!1};let l=await xe({hub:r,path:"/oauth/refresh",body:{plugin:i,tenantId:o},parseResponse:sn}),g=l.expires_in?d+l.expires_in:c?Number(c):d+3600;return await t.set_access_token(l.access_token),await t.set_expires_at(String(g)),l.refresh_token&&await t.set_refresh_token(l.refresh_token),l.scope&&await t.set_scope(l.scope),{accessToken:l.access_token,expiresAt:g,refreshed:!0}}async function jr(e,n){e._refreshAuth=async()=>(await xt(n,{forceRefresh:!0})).accessToken}function Kr(e){return{delivery:n=>Ve(e,n),deliveryOptions:n=>Ve(e,n)}}var Zr=1200*1e3;function At(){return re()}function Rt(){return Zr}function St(e,n){return qe(e,n,Zr)}function It(e,n){return Q(e,n)}function Et(e){return ke(e)}var qr=600*1e3;function _t(){return re()}function Dt(){return qr}function Ot(e,n){return qe(e,n,qr)}function Mt(e,n){return Q(e,n)}function Ht(e){return yt(e)}function Bt(e){return ke(e)}function Ut(){return re()}function Ft(e,n,t){return Dn(e,n,Math.floor(t.getTime()/1e3))}function Nt(e,n){return Q(e,n)}function $t(e){return ke(e)}function Un(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(i,o){let s=t.length>1;throw new Error(`corsair.keys.${String(o)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
24
|
+
|
|
25
|
+
To generate a KEK, run: openssl rand -base64 ${We}`)}})}var Ui=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Gr(e,n,t,r,i){let o={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(i).find(u=>i[u]?.match(e,o));return await(i[s||"DEFAULT"]?.handler||Ui)(e,o)}function Fi(e){return typeof e=="function"}function Ni(e,n,t){let r=ae(z(e,n.tenantId??t??"default"),n.kek),i=new URL(n.baseUrl);i.searchParams.set("state",r);let o=i.toString(),s=n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:o,state:r}):`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${o}`;return new Error(s)}function Lt({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:i,errorHandlers:o,currentPath:s=[],keyBuilder:a,permissionsConfig:c,endpointMeta:u,database:d,permissionsOptions:l,tenantId:g,manualConfig:f,hubConfig:p}){for(let[y,m]of Object.entries(e)){let h=n?.[y];if(Fi(m)){let C=h,b=[...s,y].join("."),k=async(w={})=>{let T;if(c){let R=u?.[b],{result:ve,reason:q,onComplete:Fe,token:X,id:fe,expiresAt:U}=await xr({pluginId:i,endpointPath:b,args:w,mode:c.mode,override:c.overrides?.[b],riskLevel:R?.riskLevel??"write",meta:R,db:d,timeoutMs:l?rt(l.timeout):void 0,tenantId:g,approvalMode:l?.mode});if(ve==="blocked"){let G;throw q==="denied"?G=`Action '${b}' was denied by the user. Await further instructions before proceeding.`:q==="policy"?G=`Action '${b}' is blocked by the permission policy. Update the corsair config to allow it.`:q==="timeout"?G=`Action '${b}' timed out waiting for approval.`:X&&fe?G=await tt({permissionsOptions:l,manual:f,hub:p,permissionId:fe,permissionToken:X,plugin:i,endpoint:b,args:w,tenantId:g??"default",expiresAt:U??new Date(Date.now()+(l?rt(l.timeout):600*1e3)).toISOString(),operationPath:b}):G=`Action '${b}' requires user approval before it can run.`,new Error(G)}T=Fe}let E=async(R,ve,q)=>{try{return await m(ve,q)}catch(Fe){if(Fe instanceof Error){let X=await Gr(Fe,i,b,typeof q=="object"&&q!==null?q:{args:q},o);if(R<(X.maxRetries||0)){let fe=R+1;console.log(`Retrying (${fe} / ${X.maxRetries})...`);let U;if(X.headersRetryAfterMs)U=X.headersRetryAfterMs;else switch(X.retryStrategy){case"exponential_backoff":U=Math.pow(2,fe-1)*1e3;break;case"exponential_backoff_jitter":let G=Math.pow(2,fe-1)*1e3,bo=(Math.random()-.5)*1e3;U=Math.max(0,G+bo);break;case"linear_1s":U=1e3;break;case"linear_2s":U=2e3;break;case"linear_3s":U=3e3;break;case"linear_4s":U=4e3;break;default:U=1e3;break}await new Promise(G=>setTimeout(G,U)),await E(fe,ve,q),console.log(`[corsair:${i}:${b}] Retry strategy:`,X)}}throw Fe}},_;try{_=a?await a(t,"endpoint"):void 0}catch(R){throw f&&Ie(f)&&f.oauthConfig&&f.kek&&R instanceof oe&&R.authType==="oauth_2"?Ni(i,f,g):R}if(!C?.before&&!C?.after){let R=await E(0,{...t,key:_},w);return await T?.(),R}let D={...t,key:_},x=C.before?await C.before(D,w):{ctx:D,args:w,continue:!0,passToAfter:void 0};if(x.continue===!1)return;let Pe=await E(0,x.ctx,x.args);return await C.after?.(x.ctx,Pe,x.passToAfter),await T?.(),Pe};r[y]=k}else if(m&&typeof m=="object"){let C={};Lt({endpoints:m,hooks:h,ctx:t,tree:C,pluginId:i,errorHandlers:o,currentPath:[...s,y],keyBuilder:a,permissionsConfig:c,endpointMeta:u,database:d,permissionsOptions:l,tenantId:g,manualConfig:f,hubConfig:p}),r[y]=C}}}function $i(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Wt({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:i}){for(let[o,s]of Object.entries(e)){let a=n?.[o];if($i(s)){let c=a,u=async d=>{let l=(f,p)=>s.handler(f,p),g=i?await i(t,"webhook"):void 0;return!c?.before&&!c?.after?l({...t,key:g},d):(async()=>{let f={...t,key:g},p=c.before?await c.before(f,d):{ctx:f,args:d,continue:!0,passToAfter:void 0};if(p.continue===!1)return;let y=await l(p.ctx,p.args);return y?.success===!0&&await c.after?.(p.ctx,y,p.passToAfter),y})()};r[o]={match:s.match,handler:u}}else if(s&&typeof s=="object"){let c={};Wt({webhooks:s,hooks:a,ctx:t,webhooksTree:c,keyBuilder:i}),r[o]=c}}}function Li(e,n,t){let r=null;return async()=>{if(r)return r;if(!e)throw new Error("Database not configured");let i=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!i)throw new Error(`Integration "${n}" not found. Make sure to create the integration first.`);let o=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",i.id).executeTakeFirst();if(!o)throw new Error(`Account not found for tenant "${t}" and integration "${n}". Make sure to create the account first.`);return r=o.id,r}}function Wi(e,n,t,r,i){return e?Wn(e.db,n,t,r,i):{findByEntityId: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 jt(e,n){let{database:t,tenantId:r,kek:i,rootErrorHandlers:o,permissionsOptions:s,manualConfig:a,hubConfig:c}=n,u={},d={};for(let l of e)u[l.id]={},d[l.id]={};for(let l of e){let g=l.schema,f=r??"default",p=Li(t,l.id,f);if(g?.entities){let x={};for(let[Pe,R]of Object.entries(g.entities)){let ve=t?Wn(t.db,p,Pe,g.version,R):Wi(void 0,p,Pe,g.version,R);x[Pe]=ve}d[l.id].db=x,u[l.id].db=x}let y=l.options,m=l.authConfig,h;if(t&&i&&y?.authType){let x=m?.[y.authType]?.account??[];h=I({authType:y.authType,integrationName:l.id,tenantId:f,kek:i,database:t,extraAccountFields:x}),u[l.id].keys=h}let C={database:t,db:d[l.id]?.db??{},$getAccountId:p,...l.options?{options:l.options}:{},...h?{keys:h,authType:y?.authType}:{},tenantId:f,...c?{hub:c}:{}},b=l.endpoints??{},k=l.hooks,w={...o,...l.errorHandlers},T={},E=l.options?.permissions;Lt({endpoints:b,hooks:k,ctx:C,tree:T,pluginId:l.id,errorHandlers:w,currentPath:[],keyBuilder:l.keyBuilder,permissionsConfig:E,endpointMeta:l.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:l.oauthConfig,kek:i,tenantId:f}:void 0,hubConfig:c}),Object.keys(T).length>0&&(u[l.id].api=T),C.endpoints=T;let _=l.webhooks??{},D=l.webhookHooks;if(Object.keys(_).length>0){let x={};Wt({webhooks:_,hooks:D,ctx:C,webhooksTree:x,keyBuilder:l.keyBuilder}),u[l.id].webhooks=x,l.pluginWebhookMatcher&&(u[l.id].pluginWebhookMatcher=l.pluginWebhookMatcher),l.pluginTenantWebhookMatcher&&(u[l.id].pluginTenantWebhookMatcher=l.pluginTenantWebhookMatcher)}}return u}function Jr(e,n,t){let r={};for(let i of e){let o=i.options,s=i.authConfig;if(o?.authType){let a=s?.[o.authType]?.integration??[],c=O({authType:o.authType,integrationName:i.id,kek:t,database:n,extraIntegrationFields:a});r[i.id]=c}}return r}var ji="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function zr(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] ${ji}`),t):n}var Vr=[{method:"GET",pattern:"/ok",handler:async()=>A(200,hn())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>A(200,await wn(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>A(201,await Tn(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>A(200,await Cn(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>A(200,await kn(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>A(200,await bn(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>A(200,await _e(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>A(200,await it(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?A(200,await at(e,t)):A(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>A(200,await Pn(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>A(200,await vn(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>A(200,await xn(e,n,t))}];(()=>{let e=new Set;for(let n of Vr){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Ki(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let i={};for(let o=0;o<t.length;o++){let s=t[o],a=r[o];if(s.startsWith(":"))i[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return i}function Zi(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 qi(e){if(!(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json")))try{let t=await e.text();return t?JSON.parse(t):void 0}catch{throw new v(400,"invalid_json","Request body is not valid JSON")}}var Gi="/api/corsair";function Ce(e,n={}){let t=n.basePath??Gi,r=P(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async i=>{try{let o=new URL(i.url),s=Zi(o.pathname,t),a=i.method.toUpperCase(),c=Object.fromEntries(o.searchParams);for(let u of Vr){if(u.method!==a)continue;let d=Ki(u.pattern,s);if(!d)continue;let l=await qi(i);return await u.handler({corsair:e,internal:r,req:i,params:d,query:c,body:l})}throw ue(`No route for ${a} ${s}`)}catch(o){if(n.onError){let a=await n.onError(o,i);if(a)return a}if(o instanceof v)return Ar(o);let s=o instanceof Error?o.message:"Internal server error";return A(500,{error:"internal_error",message:s})}}}function Ji(e){let n=e.get?.("host")??"localhost",t=e.protocol??"http",r=e.originalUrl??e.url,i=`${t}://${n}${r}`,o=new Headers;for(let[c,u]of Object.entries(e.headers))if(u!=null)if(Array.isArray(u))for(let d of u)o.append(c,d);else o.set(c,u);let s=e.method!=="GET"&&e.method!=="HEAD",a={method:e.method,headers:o};return s&&e.body!==void 0&&(a.body=typeof e.body=="string"?e.body:JSON.stringify(e.body),o.has("content-type")||o.set("content-type","application/json")),new Request(i,a)}async function zi(e,n){e.status(n.status),n.headers.forEach((r,i)=>e.setHeader(i,r));let t=Buffer.from(await n.arrayBuffer());e.send(t)}function Yr(e,n){let t=Ce(e,n);return async(r,i,o)=>{try{let s=await t(Ji(r));await zi(i,s)}catch(s){o(s)}}}function Qr(e,n){let t=Ce(e,n);return r=>t(r.req.raw)}function Xr(e,n){let t=Ce(e,n);return{GET:t,POST:t}}function eo(e){let n={[Ye]:e};return{ok:hn,tenants:{list:()=>wn(e),create:t=>Tn(e,t),get:t=>Cn(e,t)},plugins:{list:()=>kn(e),get:t=>bn(e,t)},connectionStatus:{get:t=>_e(e,t?.tenantId)},permissions:{get:t=>Dr(e,t)},connect:{createLink:t=>Pn(n,e,t),resolve:t=>vn(n,e,t),oauthCallback:t=>xn(n,e,t)}}}async function no(e,n,t,r,i="pending"){if(!e)return null;try{let o=nr(),s=new Date;return await e.db.insertInto("corsair_events").values({id:o,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:i}).execute(),o}catch(o){return console.warn("Failed to log event:",o),null}}async function Vi(e,n,t,r="pending"){try{let i=await e.$getAccountId();return no(e.database,i,n,t,r)}catch(i){return console.warn("Failed to log event:",i),null}}import*as to from"https";import*as ro from"querystring";function Fn(e,n,t,r,i){let o=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,c)=>{let u={code:e.trim(),redirect_uri:i,grant_type:"authorization_code"};s||(u.client_id=n,u.client_secret=t);let d=ro.stringify(u),l={"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(d).toString()};s&&(l.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let g=to.request({hostname:o.hostname,...o.port?{port:Number(o.port)}:{},path:o.pathname+o.search,method:"POST",headers:l},f=>{let p="";f.on("data",y=>{p+=y}),f.on("end",()=>{if(f.statusCode!==200){c(new Error(`Token exchange failed (${f.statusCode}): ${p}`));return}try{a(JSON.parse(p))}catch{c(new Error(`Token endpoint returned non-JSON response: ${p}`))}})});g.on("error",f=>c(new Error(`Request failed: ${f.message}`))),g.write(d),g.end()})}var oo=" ";function K(e){let n=e;return n._def??n.def??{}}function Z(e){let n=e.typeName;if(n)return n;let t=e.type;if(t)return`Zod${t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}`}function j(e){return e.innerType??e.schema??e.out??e.in}function so(e,n){switch(n){case"ZodPipe":return e.in??e.innerType;case"ZodEffects":return e.schema??e.innerType;case"ZodTransform":return e.schema??e.innerType??e.in;default:return j(e)}}function ao(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function $n(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function Be(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 co(e,n){return e.description??n.description}function Yi(e){let n=e;for(;n;){let t=K(n),r=co(n,t);if(r)return r;let i=Z(t);if(Jt(i)||i==="ZodPipe"||i==="ZodEffects"||i==="ZodTransform"){n=so(t,i);continue}break}}function Jt(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function M(e){let n=K(e),t=Z(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??Be(n)[0]??"unknown");case"ZodEnum":return Be(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=j(n);return r?M(r):"unknown"}case"ZodNullable":{let r=j(n);return`${r?M(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=j(n);return r?M(r):"unknown"}case"ZodArray":{let r=ao(n);if(!r)return"unknown[]";let i=K(r),o=Z(i)==="ZodUnion",s=M(r);return`${o?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=$n(e,n),i=Object.entries(r);return i.length===0?"{}":`{ ${i.map(([s,a])=>{let c=Z(K(a));return`${c==="ZodOptional"||c==="ZodNullable"?s+"?":s}: ${M(a)}`}).join(", ")} }`}case"ZodUnion":return Be(n).map(r=>M(r)).join(" | ");case"ZodIntersection":return`${M(n.left)} & ${M(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=so(n,t);return r?M(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function ie(e){let n=K(e),t=Z(n),r=co(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 i=n.value??Be(n)[0],o=typeof i=="string"||typeof i=="number"||typeof i=="boolean"?i:String(i??"");return{kind:"literal",optional:!1,description:r,value:o}}case"ZodEnum":{let i=Be(n).map(o=>String(o));return{kind:"string",optional:!1,description:r,enum:i}}case"ZodOptional":{let i=j(n),o=i?ie(i):{kind:"unknown",optional:!1};return{...o,optional:!0,description:r??o.description}}case"ZodNullable":{let i=j(n),o=i?ie(i):{kind:"unknown",optional:!1};return{...o,optional:!0,description:r??o.description}}case"ZodDefault":case"ZodCatch":{let i=j(n);return i?{...ie(i),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let i=ao(n);return{kind:"array",optional:!1,description:r,items:i?ie(i):{kind:"unknown",optional:!1}}}case"ZodObject":{let i=$n(e,n),o={};for(let[s,a]of Object.entries(i))o[s]=ie(a);return{kind:"object",optional:!1,description:r,fields:o}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let i=Be(n);for(let o of i){let s=K(o);if(Z(s)==="ZodObject")return{...ie(o),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let i=j(n);return i?{...ie(i),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function hl(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let i=t.slice(0,r),o=t.slice(r+1),s=e.find(d=>d.id===i);if(!s)return null;let a=o;a.startsWith("api.")&&(a=a.slice(4));let c=ge(s.endpointMeta,a),u=ge(s.endpointSchemas,a);return!c&&!u?null:{input:u?.input?ie(u.input):null,output:u?.output?ie(u.output):null,description:c?.description}}var zt=["equals","contains","startsWith","endsWith","in"],Qi=["equals","gt","gte","lt","lte","in"],Xi=["equals"],es=["equals","before","after","between"];function uo(e){let n=K(e);switch(Z(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=j(n);return r?uo(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Vt(e){let n=K(e),t=Z(n);if(Jt(t)){let o=j(n);return o?Vt(o):{}}if(t!=="ZodObject")return{};let r=$n(e,n),i={};for(let[o,s]of Object.entries(r)){let a=uo(s);a==="string"?i[o]={type:"string",operators:zt}:a==="number"?i[o]={type:"number",operators:Qi}:a==="boolean"?i[o]={type:"boolean",operators:Xi}:a==="date"&&(i[o]={type:"date",operators:es})}return i}function lo(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Zt(e,n,t){for(let[r,i]of Object.entries(e)){let o=[...n,r];typeof i=="function"?t.push(o.join(".")):i!==null&&typeof i=="object"&&Zt(i,o,t)}}function qt(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Gt(e,n,t){for(let[r,i]of Object.entries(e)){let o=[...n,r];qt(i)?t.push(o.join(".")):i!==null&&typeof i=="object"&&Gt(i,o,t)}}function Yt(e,n){if(n.length===0)return null;let[t,...r]=n,i=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!i)return null;let[o,s]=i;if(r.length===0)return qt(s)?[o]:null;if(s!==null&&typeof s=="object"&&!qt(s)){let a=Yt(s,r);if(a!==null)return[o,...a]}return null}function po(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let o=0;o<n.length;o++){let s=" ".repeat(o+2);t.push(`${s}${n[o]}: {`)}let r=" ".repeat(n.length+2),i=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${i}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let o=n.length-1;o>=0;o--){let s=" ".repeat(o+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
26
|
+
`)}var ns=new Set(en);function Te(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let o=e.find(a=>a.id===r);if(!o)return ns.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Te(e);if(t==="webhooks"){if(!o.webhooks)return[];let a=[];return Gt(o.webhooks,[],a),a.map(c=>`${o.id}.webhooks.${c}`)}if(t==="db"){let a=o.schema?.entities;return a?Object.keys(a).map(c=>`${o.id}.db.${c}.search`):[]}if(!o.endpoints)return[];let s=[];return Zt(o.endpoints,[],s),s.map(a=>`${o.id}.api.${a}`)}let i={};if(t==="webhooks")for(let o of e){if(!o.webhooks)continue;let s=[];Gt(o.webhooks,[],s),i[o.id]=s.map(a=>`${o.id}.webhooks.${a}`)}else if(t==="db")for(let o of e){let s=o.schema?.entities;s&&(i[o.id]=Object.keys(s).map(a=>`${o.id}.db.${a}.search`))}else for(let o of e){if(!o.endpoints)continue;let s=[];Zt(o.endpoints,[],s),i[o.id]=s.map(a=>`${o.id}.api.${a}`)}return i}function ge(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function ts(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let o=t.slice(n.length+1),s=o.startsWith(".")?o.slice(1):o;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let i=e.slice(n.length+1);return i.toLowerCase().startsWith("api.")&&(i=i.slice(4)),{shortPath:i,lookupKey:i.toLowerCase()}}function Kt(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
27
|
+
${e.join(", ")}`:`${n}:
|
|
28
|
+
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
29
|
+
`)}function kl(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let i=t.slice(0,r),o=t.slice(r+1),s=e.find(a=>a.id===i);if(s){if(o.startsWith("db.")){let d=o.slice(3),l=d.lastIndexOf(".");if(l!==-1){let g=d.slice(0,l),f=d.slice(l+1),p=s.schema?.entities;if(f==="search"&&p){let y=lo(p,g);if(y){let[m,h]=y,C=Vt(h),b=[`Search ${i} ${m} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${zt.join(", ")}]`];for(let[k,w]of Object.entries(C))b.push(` ${k}?: ${w.type} [${w.operators.join(", ")}]`);return b.push("}"),b.join(`
|
|
30
|
+
`)}}}return Kt(Te(e,{type:"db"}),"Path not found. Available db operations")}if(o.startsWith("webhooks.")){let d=o.slice(9);if(s.webhooks){let l=Yt(s.webhooks,d.split("."));if(l!==null){let g=l.join("."),f=ge(s.webhookSchemas,g.toLowerCase()),p=f?.response?M(f.response):null,y=[];return f?.description&&y.push(f.description),f?.payload&&y.push(`payload ${Nn(Ue(f.payload))}`),p&&y.push(`response: ${p}`),y.push(`usage:
|
|
31
|
+
${po(i,l)}`),y.join(`
|
|
32
|
+
|
|
33
|
+
`)}}return Kt(Te(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=o;a.startsWith("api.")&&(a=a.slice(4));let c=ge(s.endpointMeta,a),u=ge(s.endpointSchemas,a);if(c||u){let d=[],l=[c?.riskLevel?`[${c.riskLevel}]`:"",c?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),g=[c?.description,l].filter(Boolean).join(" ");return g&&d.push(g),u?.input&&d.push(`input ${Nn(Ue(u.input))}`),u?.output&&d.push(`output ${Nn(Ue(u.output))}`),d.join(`
|
|
34
|
+
|
|
35
|
+
`)}}}return Kt(Te(e),"Path not found. Available operations")}function io(e){let n=e;for(;;){let t=K(n),r=Z(t);if(Jt(r)){let i=j(t);if(!i)return n;n=i;continue}return n}}function Ue(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=io(e),t=K(n);if(Z(t)==="ZodObject"){let i=$n(n,t),o=[];for(let[s,a]of Object.entries(i)){let c=K(a),u=Z(c),d=u==="ZodOptional"||u==="ZodNullable",l=io(a),g=Yi(a);o.push({key:s,optional:d,type:M(l),...g!==void 0?{description:g}:{}})}return{kind:"object",fields:o}}return{kind:"inline",type:M(n)}}function Nn(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=oo.repeat(n+1),r=oo.repeat(n);return`{
|
|
36
|
+
${e.fields.map(o=>{let s=o.optional?`${o.key}?`:o.key,a=o.description?` // ${o.description}`:"";return`${t}${s}: ${o.type}${a}`}).join(`
|
|
37
|
+
`)}
|
|
38
|
+
${r}}`}return"unknown"}function rs(e,n){let t=Te(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(d=>d.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let i=[];for(let d of t){let{shortPath:l,lookupKey:g}=ts(d,n),f=ge(r.endpointMeta,g),p=ge(r.endpointSchemas,g);!f&&!p||i.push({path:d,shortPath:l,description:f?.description,riskLevel:f?.riskLevel,irreversible:f?.irreversible,input:Ue(p?.input),output:Ue(p?.output)})}i.sort((d,l)=>d.path.localeCompare(l.path));let o=[],s=Te(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let d of s){let g=d.toLowerCase().slice(n.length+1),f=g.startsWith(".")?g.slice(1):g;if(!f.startsWith("webhooks."))continue;let p=f.slice(9),y=Yt(r.webhooks,p.split("."));if(y===null)continue;let m=y.join("."),h=ge(r.webhookSchemas,m.toLowerCase()),C=h?.response?M(h.response):void 0;o.push({path:d,description:h?.description,payload:Ue(h?.payload),responseType:C,usageExample:po(n,y)})}o.sort((d,l)=>d.path.localeCompare(l.path));let a=[],c=Te(e,{plugin:n,type:"db"}),u=r.schema?.entities;if(Array.isArray(c)&&u)for(let d of c){let g=d.toLowerCase().slice(n.length+1),f=g.startsWith(".")?g.slice(1):g;if(!f.startsWith("db."))continue;let p=f.slice(3),y=p.lastIndexOf(".");if(y===-1)continue;let m=p.slice(0,y);if(p.slice(y+1)!=="search")continue;let C=lo(u,m);if(!C)continue;let[b,k]=C,w=Vt(k),T=Object.entries(w).map(([E,_])=>({field:E,type:_.type,operators:_.operators}));a.push({path:d,entityName:b,filters:[{field:"entity_id",type:"string",operators:zt},...T]})}return a.sort((d,l)=>d.path.localeCompare(l.path)),{ok:!0,data:{pluginId:n,api:i,webhooks:o,db:a}}}function go(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function os(e,n){let t=go(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let i=r.pluginTenantWebhookMatcher(n);return i?{plugin:t,tenantMatch:i}:null}function is(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function fo(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function yo(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 Qe(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function ss(e){return Qe(e.body)}function mo(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Ln(Array.isArray(r)?r:[r])}function ho(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let u=Ln(Array.isArray(c)?c:[c]);if(u)return decodeURIComponent(u)}let r=mo({query:e.query},"validationToken");if(r)return r;let i=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let c of i){let u=n[c],d=Array.isArray(u)?u[0]:u;if(!(!d||typeof d!="string"))try{let g=(d.startsWith("http")?new URL(d):new URL(`https://example.invalid${d.startsWith("/")?d:`/${d}`}`)).searchParams.get("validationToken");if(g?.trim())return g.trim()}catch{continue}}let o=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Qe(typeof o=="string"?(()=>{try{return JSON.parse(o)}catch{return o}})():o);return Ln([s?.validationToken])??null}function as(e){if(ho(e))return!0;let n=Qe(e.body??e.payload);return fo(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Ln(e){for(let n of e){let t=yo(n);if(t)return t}}function cs(e){let t=Qe(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Ye=Symbol.for("corsair:internal");function lr(e){let n=e.database?Qt(e.database):void 0,t=n&&e.kek?Jr(e.plugins,n,e.kek):Un(!!n,!!e.kek),r=zr(e),i={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?nn(e.hub):void 0},o=vr(n),s=eo(i);if(e.multiTenancy)return Object.assign({withTenant:c=>{if(!c)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let u=jt(e.plugins,{database:n,tenantId:c,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:i.hub});return Object.assign(u,{[Ye]:i})},keys:t,permissions:o,manage:s},{[Ye]:i});let a=jt(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:i.hub});return Object.assign({},a,{keys:t,permissions:o,manage:s,[Ye]:i})}var B=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ko(e){let n=e.oauthConfig;if(!n)throw new B("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function us(e,n,t,r){let i=rr(e),o=await i.integrations.findByName(n);if(!o)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await i.accounts.findOne({tenant_id:t,integration_id:o.id}))return;let a=ee(),c=await ne(a,r);await i.accounts.create({tenant_id:t,integration_id:o.id,config:{},dek:c})}async function Jn(e,n,t){let{tenantId:r,redirectUri:i}=t,o=P(e,()=>new B("invalid_corsair_instance","Invalid corsair instance"));if(!o.database)throw new Error("No database configured on corsair instance");let s=F(o,n,l=>new B("plugin_not_found",l)),a=ko(s),u=await O({authType:"oauth_2",integrationName:n,kek:o.kek,database:o.database}).get_client_id();if(!u)throw new Error(`client_id not configured for '${n}'`);let d=ae(z(n,r),o.kek);return{url:Ee({oauthConfig:a,clientId:u,redirectUri:i,state:d}),state:d}}async function ze(e,n){let{code:t,state:r,redirectUri:i}=n,o=P(e,()=>new B("invalid_corsair_instance","Invalid corsair instance")),s=cn(r,o.kek);if(!s)throw new B("invalid_state","Invalid or tampered state parameter");let{plugin:a,tenantId:c}=s;if(!o.database)throw new B("no_database","No database configured on corsair instance");let u=F(o,a,m=>new B("plugin_not_found",m)),d=ko(u),l=O({authType:"oauth_2",integrationName:a,kek:o.kek,database:o.database}),g=await l.get_client_id(),f=await l.get_client_secret();if(!g||!f)throw new B("credentials_not_configured",`Credentials not configured for '${a}'`);await us(o.database,a,c,o.kek);let p=await Fn(t,g,f,d,i);if(!p.access_token)throw new B("no_access_token",`No access_token returned from ${d.providerName}`);let y=I({authType:"oauth_2",integrationName:a,tenantId:c,kek:o.kek,database:o.database});await y.set_access_token(p.access_token),p.refresh_token&&await y.set_refresh_token(p.refresh_token),p.expires_in&&await y.set_expires_at(String(Math.floor(Date.now()/1e3)+p.expires_in));try{let m=await In(o.plugins,a,p);if(m)try{let h=u.authConfig?.oauth_2?.account??[];await Oe({database:o.database,kek:o.kek,pluginId:a,tenantId:c,link:m,authType:"oauth_2",extraAccountFields:h})}catch(h){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${a}' tenant '${c}':`,h)}}catch(m){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${a}' tenant '${c}':`,m)}return{plugin:a,tenantId:c}}export{or as a,ye as b,Ne as c,me as d,nn as e,H as f,tn as g,rn as h,on as i,sn as j,ir as k,an as l,z as m,jn as n,ee as o,ne as p,L as q,zn as r,je as s,ce as t,te as u,Ke as v,O as w,I as x,br as y,wr as z,Oe as A,ct as B,En as C,Mr as D,Ee as E,B as F,Jn as G,ze as H,Le as I,Ae as J,Zn as K,sr as L,Re as M,cr as N,Ko as O,ln as P,Yn as Q,fn as R,yn as S,De as T,le as U,he as V,de as W,Me as X,Br as Y,_n as Z,lt as _,He as $,dt as aa,pt as ba,gt as ca,ft as da,re as ea,On as fa,Mn as ga,pe as ha,be as ia,we as ja,Ge as ka,Je as la,Hn as ma,kt as na,bt as oa,wt as pa,Ct as qa,Tt as ra,Pt as sa,vt as ta,Ve as ua,oe as va,xt as wa,jr as xa,Kr as ya,At as za,Rt as Aa,St as Ba,It as Ca,Et as Da,_t as Ea,Dt as Fa,Ot as Ga,Mt as Ha,Ht as Ia,Bt as Ja,Ut as Ka,Ft as La,Nt as Ma,$t as Na,Ce as Oa,Yr as Pa,Qr as Qa,Xr as Ra,no as Sa,Vi as Ta,Fn as Ua,hl as Va,Te as Wa,kl as Xa,Nn as Ya,rs as Za,go as _a,os as $a,is as ab,fo as bb,yo as cb,Qe as db,ss as eb,mo as fb,ho as gb,as as hb,Ln as ib,cs as jb,Ye as kb,lr as lb};
|
package/dist/core.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-
|
|
1
|
+
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-SNBBST6f.js';
|
|
2
2
|
import { CorsairDatabase } from './db.js';
|
|
3
|
-
import { A as AuthTypes, a as AccountKeyManagerFor, I as IntegrationKeyManagerFor } from './types-
|
|
4
|
-
export { b as AccountFieldNames, f as AllProviders, e as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, c as BaseKeyManager, g as BaseProviders, k as Bivariant, d as IntegrationFieldNames, O as OAuth2IntegrationCredentials, h as PickAuth, P as PluginAuthConfig, j as ProviderDisplayNames, U as UnionToIntersection, i as formatProviderDisplayName } from './types-
|
|
5
|
-
export {
|
|
6
|
-
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, j as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, k as asRecord, g as collectPluginWebhookMatchers, l as decodePubSubData, n as extractMicrosoftGraphValidationToken, o as firstString, f as formatDocSchemaShape, p as getHeader, i as introspectPluginForDocs, q as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, h as matchWebhookPluginAndTenant, s as readBodyRecord, t as readQueryParam, r as resolveConnectLink, u as toExternalId } from './tenant-match-utils-
|
|
3
|
+
import { A as AuthTypes, a as AccountKeyManagerFor, I as IntegrationKeyManagerFor } from './types-C2vFipdU.js';
|
|
4
|
+
export { b as AccountFieldNames, f as AllProviders, e as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, c as BaseKeyManager, g as BaseProviders, k as Bivariant, d as IntegrationFieldNames, O as OAuth2IntegrationCredentials, h as PickAuth, P as PluginAuthConfig, j as ProviderDisplayNames, U as UnionToIntersection, i as formatProviderDisplayName } from './types-C2vFipdU.js';
|
|
5
|
+
export { v as BeforeHookResult, B as BindEndpoints, N as BindWebhooks, h as BoundEndpointFn, i as BoundEndpointTree, Q as BoundWebhook, S as BoundWebhookTree, g as CorsairClient, j as CorsairContext, k as CorsairEndpoint, m as CorsairErrorHandler, c as CorsairIntegration, w as CorsairKeyBuilder, x as CorsairKeyBuilderBase, U as CorsairOAuthWebhookTenantLinkResolver, s as CorsairPermissionsNamespace, C as CorsairPlugin, y as CorsairPluginContext, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, V as CorsairWebhook, X as CorsairWebhookHandler, Y as CorsairWebhookMatcher, Z as CorsairWebhookTenantMatcher, z as EndpointHooks, A as EndpointMetaEntry, E as EndpointPathsOf, D as EndpointRiskLevel, l as EndpointTree, t as EnforcePermissionOptions, u as EnforcePermissionResult, n as ErrorContext, o as ErrorHandler, p as ErrorHandlerAndMatchFunction, q as ErrorMatcher, K as KeyBuilderContext, O as OAuthConfig, P as PermissionMode, F as PermissionPolicy, G as PluginEndpointMeta, H as PluginPermissionsConfig, _ as RawWebhookRequest, I as RequiredPluginEndpointMeta, J as RequiredPluginEndpointSchemas, L as RequiredPluginWebhookSchemas, R as RetryStrategies, r as RetryStrategy, T as TokenResponse, M as WebhookHooks, $ as WebhookPathsOf, a0 as WebhookRequest, a1 as WebhookResponse, W as WebhookTenantMatch, a2 as WebhookTree, f as exchangeCodeForTokens } from './index-CnnnYiGH.js';
|
|
6
|
+
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, j as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, k as asRecord, g as collectPluginWebhookMatchers, l as decodePubSubData, n as extractMicrosoftGraphValidationToken, o as firstString, f as formatDocSchemaShape, p as getHeader, i as introspectPluginForDocs, q as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, h as matchWebhookPluginAndTenant, s as readBodyRecord, t as readQueryParam, r as resolveConnectLink, u as toExternalId } from './tenant-match-utils-CMI2112T.js';
|
|
7
7
|
import 'kysely';
|
|
8
8
|
import 'zod';
|
|
9
9
|
import 'pg';
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{$a as x,Q as p,Sa as r,Ta as s,Ua as t,Ya as u,Za as v,_a as w,a,ab as y,b,bb as z,cb as A,db as B,eb as C,fb as D,gb as E,hb as F,ib as G,jb as H,kb as I,lb as J,o as d,p as e,q as f,r as g,s as h,t as i,u as j,v as k,va as q,w as l,x as m,y as n,z as o}from"./chunk-2LV4I6JX.js";import{g as c}from"./chunk-NZS35HPL.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{q as AuthMissingError,c as BASE_AUTH_FIELDS,I as CORSAIR_INTERNAL,a as ProviderDisplayNames,B as asRecord,y as collectPluginWebhookMatchers,m as createAccountKeyManager,J as createCorsair,l as createIntegrationKeyManager,H as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,t as exchangeCodeForTokens,E as extractMicrosoftGraphValidationToken,G as firstString,u as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,z as getHeader,o as initializeAccountDEK,n as initializeIntegrationDEK,v as introspectPluginForDocs,F as isMicrosoftGraphValidationHandshake,r as logEvent,s as logEventFromContext,w as matchWebhookPlugin,x as matchWebhookPluginAndTenant,k as reEncryptConfig,C as readBodyRecord,D as readQueryParam,p as resolveConnectLink,A as toExternalId};
|