@oomol-lab/open-connector 1.9.2 → 1.9.3
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/README.md +4 -2
- package/assets/open-connector/catalog/apps/allratestoday.json +174 -0
- package/assets/open-connector/catalog/apps/slackbot.json +20 -1
- package/assets/open-connector/catalog/apps-index.json +1 -1
- package/package.json +1 -1
- package/src/connection-error.d.ts +7 -0
- package/src/connection-error.js +10 -0
- package/src/connection-service.d.ts +2 -50
- package/src/connection-service.js +6 -130
- package/src/connection-store.d.ts +41 -0
- package/src/connection-store.js +1 -0
- package/src/core/guarded-fetch.d.ts +3 -0
- package/src/core/guarded-fetch.js +8 -1
- package/src/core/provider-network-policy.d.ts +15 -0
- package/src/core/provider-network-policy.js +11 -0
- package/src/core/request.d.ts +18 -14
- package/src/core/request.js +11 -35
- package/src/credential-resolver.d.ts +24 -0
- package/src/credential-resolver.js +131 -0
- package/src/mcp.js +1 -1
- package/src/oauth/oauth-client-config-service.d.ts +1 -1
- package/src/oauth/oauth-client-config-service.js +14 -2
- package/src/oauth/oauth-credential-refresh-service.js +1 -1
- package/src/oauth/oauth-flow-service.d.ts +9 -1
- package/src/oauth/oauth-flow-service.js +11 -1
- package/src/providers/abuseipdb/executors.js +3 -4
- package/src/providers/action-contracts.generated.d.ts +1 -0
- package/src/providers/addressfinder/executors.js +2 -3
- package/src/providers/aeroleads/executors.js +3 -3
- package/src/providers/affinity/runtime.js +6 -7
- package/src/providers/aftership/executors.js +2 -2
- package/src/providers/agent_mail/runtime.js +2 -2
- package/src/providers/agentql/runtime.js +2 -2
- package/src/providers/agenty/runtime.js +5 -6
- package/src/providers/agiled/runtime.d.ts +0 -1
- package/src/providers/agiled/runtime.js +2 -3
- package/src/providers/agility/runtime.js +2 -3
- package/src/providers/ahrefs/runtime.js +3 -3
- package/src/providers/aifinmarket/runtime.js +6 -7
- package/src/providers/airtable/executors.js +3 -3
- package/src/providers/alchemy/runtime.js +2 -2
- package/src/providers/algolia/runtime.js +3 -3
- package/src/providers/aliyun_oss/executors.js +7 -7
- package/src/providers/allratestoday/executors.d.ts +3 -0
- package/src/providers/allratestoday/executors.js +18 -0
- package/src/providers/allratestoday/runtime.d.ts +17 -0
- package/src/providers/allratestoday/runtime.js +104 -0
- package/src/providers/alpaca/runtime.js +2 -3
- package/src/providers/alpha_vantage/runtime.js +2 -2
- package/src/providers/alt_text_ai/runtime.js +2 -2
- package/src/providers/altiria/executors.js +3 -3
- package/src/providers/amap/runtime.js +3 -3
- package/src/providers/ambee/runtime.js +2 -2
- package/src/providers/ambivo/executors.js +3 -3
- package/src/providers/amilia/runtime.js +1 -1
- package/src/providers/amplemarket/runtime.js +2 -2
- package/src/providers/amplitude/runtime.js +3 -3
- package/src/providers/anysearch/runtime.js +4 -4
- package/src/providers/apaleo/runtime.js +2 -2
- package/src/providers/api_sports/executors.js +3 -4
- package/src/providers/apiverve/executors.js +2 -3
- package/src/providers/apollo/executors.js +2 -3
- package/src/providers/appcircle/runtime.js +5 -5
- package/src/providers/appdrag/executors.js +2 -3
- package/src/providers/arcgis_online/executors.js +2 -2
- package/src/providers/auth0_management/runtime.js +2 -3
- package/src/providers/autoblogger/executors.js +3 -3
- package/src/providers/baidu_maps/runtime.js +3 -3
- package/src/providers/baidu_netdisk/runtime-mcp.js +3 -4
- package/src/providers/bark/executors.js +5 -5
- package/src/providers/bitrise/runtime.js +3 -3
- package/src/providers/bouncer/executors.js +3 -4
- package/src/providers/browse_ai/runtime.js +3 -4
- package/src/providers/browserstack/executors.js +6 -7
- package/src/providers/buildkite/runtime.js +3 -3
- package/src/providers/bunnycdn/runtime.js +3 -3
- package/src/providers/businessmap/runtime.js +6 -7
- package/src/providers/buttondown/runtime.js +2 -2
- package/src/providers/byteforms/runtime.js +2 -2
- package/src/providers/calendly/runtime.js +2 -2
- package/src/providers/captainbi/runtime.js +6 -6
- package/src/providers/castingwords/runtime.js +1 -1
- package/src/providers/chatpdf/runtime.js +4 -4
- package/src/providers/check/executors.js +3 -4
- package/src/providers/checkly/executors.js +3 -4
- package/src/providers/chengxin/runtime.js +3 -3
- package/src/providers/cincopa/executors.js +3 -4
- package/src/providers/circle/executors.js +3 -4
- package/src/providers/clearout/executors.js +1 -2
- package/src/providers/clickhelp/runtime.js +5 -5
- package/src/providers/clickhouse/runtime.js +4 -4
- package/src/providers/clinicalkey/runtime.js +3 -3
- package/src/providers/clinicaltrials_gov/runtime.js +4 -5
- package/src/providers/clockify/runtime.js +4 -4
- package/src/providers/close/runtime.js +3 -3
- package/src/providers/cloudconvert/runtime.js +8 -9
- package/src/providers/cloudflare_dns/runtime.js +2 -2
- package/src/providers/cloudflare_email_routing/runtime.js +2 -2
- package/src/providers/cloudflare_r2/runtime.js +5 -5
- package/src/providers/cloudflare_worker/runtime.js +10 -10
- package/src/providers/cloudinary/runtime.js +4 -4
- package/src/providers/cloudlayer/runtime.js +5 -5
- package/src/providers/codacy/runtime.js +2 -2
- package/src/providers/codemagic/runtime.js +2 -2
- package/src/providers/confluence/executors.js +4 -4
- package/src/providers/confluence/runtime.d.ts +0 -1
- package/src/providers/confluence/runtime.js +6 -7
- package/src/providers/contactout/runtime.js +5 -5
- package/src/providers/contentful/runtime.js +2 -2
- package/src/providers/contentstack_content_delivery/runtime.js +1 -1
- package/src/providers/cronly/runtime.js +2 -2
- package/src/providers/crossref/runtime.js +3 -3
- package/src/providers/cutt_ly/runtime.js +3 -3
- package/src/providers/cyberimpact/runtime.js +3 -3
- package/src/providers/dachser/executors.js +2 -2
- package/src/providers/dailybot/runtime.js +1 -1
- package/src/providers/databox/runtime.js +2 -2
- package/src/providers/databricks/runtime.js +2 -2
- package/src/providers/datacite/runtime.js +1 -1
- package/src/providers/datadog/executors.js +3 -4
- package/src/providers/datascope/runtime.js +2 -2
- package/src/providers/daytona/executors.js +3 -3
- package/src/providers/deepgram/runtime.js +2 -2
- package/src/providers/deepl/runtime.js +4 -4
- package/src/providers/detrack/executors.js +5 -5
- package/src/providers/deutschlandgpt/runtime.js +2 -2
- package/src/providers/dialmycalls/runtime.js +4 -4
- package/src/providers/diffbot/executors.js +4 -4
- package/src/providers/digistore24/executors.js +3 -3
- package/src/providers/dingtalk_bot/executors.js +1 -1
- package/src/providers/discourse/executors.d.ts +0 -1
- package/src/providers/discourse/executors.js +6 -7
- package/src/providers/docugenerate/runtime.js +3 -3
- package/src/providers/doppler/runtime.shared.js +3 -3
- package/src/providers/doppler_marketing_automation/runtime.js +4 -4
- package/src/providers/dovetail/runtime.js +2 -2
- package/src/providers/dropcontact/runtime.js +3 -3
- package/src/providers/dub/executors.js +6 -6
- package/src/providers/dumplingai/runtime.js +2 -2
- package/src/providers/elevenlabs/executors.js +4 -4
- package/src/providers/elevenreader/runtime.js +1 -1
- package/src/providers/emailoctopus/runtime.js +4 -4
- package/src/providers/embase/runtime.js +3 -3
- package/src/providers/emelia/executors.js +2 -2
- package/src/providers/enigma/executors.js +3 -3
- package/src/providers/eodhd_apis/executors.js +2 -2
- package/src/providers/eventzilla/runtime.js +3 -4
- package/src/providers/evervault/runtime.js +1 -1
- package/src/providers/excalidraw_mcp/runtime.js +3 -4
- package/src/providers/excel/runtime.js +6 -6
- package/src/providers/expofp/runtime.js +2 -2
- package/src/providers/faktoora/runtime.js +5 -5
- package/src/providers/fast_note_sync/runtime.js +2 -2
- package/src/providers/feathery/executors.js +2 -3
- package/src/providers/feishu_app_bot/executors.js +2 -3
- package/src/providers/feishu_custom_bot/executors.js +2 -3
- package/src/providers/ffhub/executors.js +2 -3
- package/src/providers/fidel_api/executors.js +2 -3
- package/src/providers/files_com/executors.js +2 -3
- package/src/providers/fireberry/runtime.d.ts +0 -1
- package/src/providers/fireberry/runtime.js +3 -4
- package/src/providers/firehydrant/executors.js +2 -3
- package/src/providers/float/executors.js +2 -3
- package/src/providers/flomo/executors.js +5 -6
- package/src/providers/flowiseai/executors.js +2 -3
- package/src/providers/fluxguard/executors.js +2 -3
- package/src/providers/folk/executors.js +2 -3
- package/src/providers/football_data/executors.js +2 -3
- package/src/providers/forem/executors.js +2 -3
- package/src/providers/formbricks/executors.js +2 -3
- package/src/providers/formsite/executors.js +3 -4
- package/src/providers/formspree/executors.js +2 -2
- package/src/providers/freshdesk/executors.js +3 -4
- package/src/providers/freshservice/executors.js +3 -4
- package/src/providers/freshteam/runtime.js +3 -4
- package/src/providers/full_contact/executors.js +3 -3
- package/src/providers/fusion-api/runtime.js +2 -3
- package/src/providers/gagelist/executors.js +3 -3
- package/src/providers/gainsight_nxt/executors.js +2 -2
- package/src/providers/gamma/executors.js +4 -3
- package/src/providers/gangtise/runtime.js +3 -4
- package/src/providers/gatherup/runtime.js +1 -1
- package/src/providers/geckoboard/executors.js +2 -3
- package/src/providers/gemini/runtime.d.ts +0 -1
- package/src/providers/gemini/runtime.js +5 -6
- package/src/providers/genpage/runtime.js +2 -2
- package/src/providers/geokeo/executors.js +4 -4
- package/src/providers/getnote/runtime.js +2 -3
- package/src/providers/github/runtime-shared.js +2 -2
- package/src/providers/glyphic/runtime.js +3 -4
- package/src/providers/gmail/executors.js +125 -27
- package/src/providers/gong/runtime.js +6 -7
- package/src/providers/googlecalendar/runtime-shared.js +3 -4
- package/src/providers/googledrive/runtime-request.js +2 -3
- package/src/providers/googlesheets/runtime-shared.js +3 -4
- package/src/providers/gorgias/runtime.js +4 -4
- package/src/providers/gotify/executors.js +7 -8
- package/src/providers/greenhouse/executors.js +3 -3
- package/src/providers/gumloop/executors.js +2 -3
- package/src/providers/gumroad/executors.js +2 -3
- package/src/providers/habitica/executors.js +2 -3
- package/src/providers/hackerrank_work/executors.js +2 -3
- package/src/providers/harvest/executors.js +3 -4
- package/src/providers/haveibeenpwned/executors.js +2 -3
- package/src/providers/headout/executors.js +3 -4
- package/src/providers/healthchecks_io/executors.js +2 -3
- package/src/providers/helium10/runtime.js +4 -5
- package/src/providers/helpdesk/runtime.js +4 -4
- package/src/providers/home_assistant/runtime-ws.js +9 -10
- package/src/providers/hotjar/executors.js +4 -4
- package/src/providers/httpsms/runtime.js +3 -4
- package/src/providers/hub_planner/executors.js +3 -3
- package/src/providers/hubspot/runtime.js +3 -4
- package/src/providers/humaans/runtime.js +3 -3
- package/src/providers/hunter/runtime.js +3 -3
- package/src/providers/icypeas/executors.js +3 -4
- package/src/providers/ima/runtime.js +7 -7
- package/src/providers/infolobby/runtime.js +6 -6
- package/src/providers/instabot/runtime.js +6 -6
- package/src/providers/instatus/runtime.js +4 -4
- package/src/providers/intuiface/executors.js +3 -3
- package/src/providers/iplocate/runtime.js +4 -5
- package/src/providers/ipregistry/executors.js +2 -2
- package/src/providers/jiminny/runtime.js +4 -4
- package/src/providers/jin10/executors.js +4 -5
- package/src/providers/jira/executors.js +4 -4
- package/src/providers/kaleido/runtime.js +2 -2
- package/src/providers/kandji/runtime.js +2 -2
- package/src/providers/keygen/executors.js +4 -4
- package/src/providers/keyword/runtime.js +2 -2
- package/src/providers/kie_ai/executors.js +1 -1
- package/src/providers/kintone/runtime.js +1 -1
- package/src/providers/kit/runtime.js +2 -2
- package/src/providers/klangio/runtime.js +4 -4
- package/src/providers/klaviyo/executors.js +1 -1
- package/src/providers/klazify/executors.js +3 -3
- package/src/providers/klipfolio/runtime.js +3 -3
- package/src/providers/knack/executors.js +1 -1
- package/src/providers/kommo/runtime.js +2 -2
- package/src/providers/kontent_ai/executors.js +3 -4
- package/src/providers/l2s/executors.js +3 -4
- package/src/providers/latchshot/executors.js +2 -2
- package/src/providers/leadboxer/runtime.js +4 -4
- package/src/providers/leadiq/runtime.js +4 -4
- package/src/providers/linguapop/runtime.js +1 -1
- package/src/providers/lingvanex_translation_api/runtime.js +5 -6
- package/src/providers/lingxing_mcp/runtime.js +3 -4
- package/src/providers/linkup/runtime.js +5 -6
- package/src/providers/liveagent/executors.js +6 -6
- package/src/providers/loops/executors.js +2 -2
- package/src/providers/loyjoy/runtime.js +2 -2
- package/src/providers/loyverse/executors.js +4 -4
- package/src/providers/lusha/runtime.js +3 -3
- package/src/providers/mailbluster/runtime.js +3 -4
- package/src/providers/mailcoach/runtime.js +4 -4
- package/src/providers/mailgenius/executors.js +3 -4
- package/src/providers/mailjet/runtime.js +3 -3
- package/src/providers/mails_so/runtime.js +1 -1
- package/src/providers/mailsoftly/runtime.js +5 -5
- package/src/providers/mailtrap/runtime.js +4 -5
- package/src/providers/manus/runtime.js +3 -3
- package/src/providers/mautic/runtime.js +3 -3
- package/src/providers/megaventory/runtime.js +3 -3
- package/src/providers/memberstack/runtime.js +2 -2
- package/src/providers/mendeley/executors.js +2 -3
- package/src/providers/mindbody/runtime.js +3 -3
- package/src/providers/minerstat/executors.js +3 -3
- package/src/providers/mintlify/runtime.js +3 -3
- package/src/providers/missive/executors.js +3 -5
- package/src/providers/mixpanel/executors.js +3 -3
- package/src/providers/mobile_text_alerts/runtime.js +3 -3
- package/src/providers/mocean/executors.js +3 -3
- package/src/providers/moco/executors.js +5 -5
- package/src/providers/moesif/runtime.js +4 -4
- package/src/providers/monday/runtime-common.js +3 -3
- package/src/providers/monica_crm/runtime.js +4 -4
- package/src/providers/moorcheh/runtime.js +3 -3
- package/src/providers/more_trees/runtime.d.ts +0 -1
- package/src/providers/more_trees/runtime.js +7 -8
- package/src/providers/moxie/runtime.js +2 -2
- package/src/providers/msg91/runtime.js +4 -4
- package/src/providers/mx/runtime.js +1 -1
- package/src/providers/needle/runtime.js +3 -4
- package/src/providers/netlify/runtime.js +2 -3
- package/src/providers/niftyimages/executors.js +2 -2
- package/src/providers/northbeam/runtime.js +1 -1
- package/src/providers/nozbe_teams/executors.js +4 -4
- package/src/providers/npm/runtime.js +4 -4
- package/src/providers/nusii_proposals/runtime.js +2 -2
- package/src/providers/ocr_web_service/executors.js +4 -4
- package/src/providers/octopus_deploy/executors.js +3 -3
- package/src/providers/oksign/runtime.js +3 -4
- package/src/providers/one_drive/executors.js +6 -6
- package/src/providers/one_password_events/runtime.js +1 -1
- package/src/providers/onfleet/runtime.js +3 -3
- package/src/providers/onlyoffice_docspace/runtime.js +4 -4
- package/src/providers/oomnitza/runtime.js +3 -4
- package/src/providers/otter_ai/executors.js +2 -2
- package/src/providers/oura/runtime.js +1 -1
- package/src/providers/paddle/executors.js +3 -3
- package/src/providers/pagerduty/runtime.js +2 -2
- package/src/providers/paradym/runtime.js +4 -4
- package/src/providers/parallel/runtime.js +3 -3
- package/src/providers/partner_stack_partner/runtime.js +1 -1
- package/src/providers/payrexx/runtime.js +5 -6
- package/src/providers/permit_io/runtime.js +2 -2
- package/src/providers/pinboard/executors.js +5 -6
- package/src/providers/pinpoint/runtime.js +2 -2
- package/src/providers/placid/runtime.js +3 -3
- package/src/providers/plain/runtime.js +5 -5
- package/src/providers/planetscale/runtime.js +2 -2
- package/src/providers/planhat/executors.js +6 -6
- package/src/providers/plausible_analytics/runtime.js +3 -3
- package/src/providers/posthog/runtime.js +3 -3
- package/src/providers/predis_ai/executors.js +3 -3
- package/src/providers/printavo/runtime.js +2 -2
- package/src/providers/prospeo/runtime.js +2 -3
- package/src/providers/provider-runtime.d.ts +13 -1
- package/src/providers/provider-runtime.js +25 -10
- package/src/providers/push_by_techulus/executors.js +3 -4
- package/src/providers/pushover/runtime.js +4 -5
- package/src/providers/pushsafer/runtime.js +4 -5
- package/src/providers/pylon/runtime.js +2 -2
- package/src/providers/qase/runtime.js +3 -3
- package/src/providers/qdrant/runtime.js +1 -1
- package/src/providers/qichacha/runtime.js +2 -2
- package/src/providers/qingflow/runtime.js +2 -2
- package/src/providers/quickchart/runtime.js +2 -2
- package/src/providers/quintadb/runtime.js +2 -2
- package/src/providers/quo/runtime.js +2 -2
- package/src/providers/rawg/runtime.js +4 -4
- package/src/providers/razorpay/runtime.js +4 -5
- package/src/providers/readme/runtime.js +6 -6
- package/src/providers/referralhero/runtime.js +3 -3
- package/src/providers/registry.generated.js +1 -0
- package/src/providers/render/executors.js +3 -3
- package/src/providers/respond_io/executors.js +3 -3
- package/src/providers/reversecontact/runtime.js +3 -3
- package/src/providers/ritekit/executors.js +2 -2
- package/src/providers/riveter/executors.js +2 -3
- package/src/providers/rocket_chat/executors.js +3 -4
- package/src/providers/rocket_reach/executors.js +3 -4
- package/src/providers/saucelabs/runtime.js +4 -4
- package/src/providers/scopus/runtime.js +3 -3
- package/src/providers/scrape_do/executors.js +2 -2
- package/src/providers/scraperapi/runtime.js +4 -4
- package/src/providers/scrapfly/executors.js +2 -2
- package/src/providers/scrapingant/executors.js +6 -7
- package/src/providers/scrapingbee/executors.js +3 -3
- package/src/providers/scrapingdog/executors.js +1 -1
- package/src/providers/screenshot_fyi/executors.js +3 -4
- package/src/providers/screenshotbase/runtime.js +3 -3
- package/src/providers/search_api/runtime.js +2 -2
- package/src/providers/securitytrails/executors.js +2 -2
- package/src/providers/semantic_scholar/executors.js +2 -2
- package/src/providers/sendbird/executors.js +2 -2
- package/src/providers/sendfox/executors.js +3 -3
- package/src/providers/sendgrid/executors.js +5 -5
- package/src/providers/sendmator/runtime.js +3 -4
- package/src/providers/seqera/runtime.js +3 -4
- package/src/providers/serveravatar/executors.js +3 -3
- package/src/providers/sheetdb/runtime.js +2 -2
- package/src/providers/short_menu/runtime.js +3 -3
- package/src/providers/shortcut/runtime.js +3 -3
- package/src/providers/shortpixel/runtime.js +2 -2
- package/src/providers/shotstack/runtime.js +4 -4
- package/src/providers/signpath/runtime.js +2 -2
- package/src/providers/signwell/runtime.js +5 -6
- package/src/providers/similarweb_digitalrank_api/runtime.js +3 -3
- package/src/providers/simla/runtime.js +5 -5
- package/src/providers/simplybook_me/executors.js +6 -6
- package/src/providers/sitespeakai/runtime.js +3 -3
- package/src/providers/slickdeals/runtime.js +2 -3
- package/src/providers/smartsuite/runtime.js +3 -3
- package/src/providers/sonarcloud/runtime.js +5 -5
- package/src/providers/sorftime/runtime.js +8 -8
- package/src/providers/spider/runtime.js +2 -2
- package/src/providers/splunk_http_event_collector/runtime.js +7 -8
- package/src/providers/sportsdata/runtime.js +4 -4
- package/src/providers/spyfu/runtime.js +4 -5
- package/src/providers/square/runtime.js +4 -4
- package/src/providers/stannp/runtime.js +2 -2
- package/src/providers/stripe/executors.js +2 -2
- package/src/providers/supermemory/runtime.js +3 -3
- package/src/providers/survey_monkey/runtime.js +3 -3
- package/src/providers/taiga/runtime.js +4 -4
- package/src/providers/talenox/executors.js +4 -4
- package/src/providers/tally/runtime.js +3 -3
- package/src/providers/tavily/runtime.js +3 -4
- package/src/providers/teamcamp/executors.js +2 -2
- package/src/providers/teamtailor/executors.js +2 -2
- package/src/providers/telegram/executors.js +6 -7
- package/src/providers/teltel/executors.js +2 -2
- package/src/providers/templated/executors.js +3 -3
- package/src/providers/tencent_docs/runtime.js +4 -4
- package/src/providers/tencent_maps/runtime.js +3 -3
- package/src/providers/textcortex/runtime.js +3 -3
- package/src/providers/the_cat_api/runtime.js +3 -3
- package/src/providers/the_colony/runtime.js +3 -3
- package/src/providers/the_odds_api/runtime.js +3 -4
- package/src/providers/the_official_board/runtime.js +4 -4
- package/src/providers/thehive/runtime.js +1 -1
- package/src/providers/tikhub/endpoint-catalog.js +2 -3
- package/src/providers/tiktok_business/runtime.js +2 -2
- package/src/providers/timecamp/runtime.js +2 -2
- package/src/providers/timelink/runtime.js +2 -2
- package/src/providers/totp/runtime.js +4 -5
- package/src/providers/trawlingweb/runtime.js +2 -2
- package/src/providers/trilium/runtime.js +2 -2
- package/src/providers/triple_whale/runtime.js +3 -3
- package/src/providers/truvera/runtime.js +2 -2
- package/src/providers/tuskr/runtime.js +2 -2
- package/src/providers/typebot/runtime.js +2 -2
- package/src/providers/typeform/runtime.js +2 -2
- package/src/providers/uptimerobot/executors.js +3 -4
- package/src/providers/v2ex/runtime.js +8 -9
- package/src/providers/valyu/runtime.js +3 -3
- package/src/providers/vapi/runtime.js +4 -4
- package/src/providers/vectorshift/runtime.js +3 -3
- package/src/providers/venafitlsprotectcloud/runtime.js +2 -3
- package/src/providers/venafitlsprotectdatacenter/runtime.js +2 -3
- package/src/providers/vida/runtime.js +4 -4
- package/src/providers/vonage/runtime.js +3 -3
- package/src/providers/walmart_marketplace/runtime.js +5 -5
- package/src/providers/weatherapi/executors.js +3 -4
- package/src/providers/web_of_science/runtime.js +4 -4
- package/src/providers/web_of_science_expanded/runtime.js +9 -9
- package/src/providers/webex/runtime.js +3 -3
- package/src/providers/webinarjam/runtime.js +4 -4
- package/src/providers/webscraping_ai/runtime.js +3 -3
- package/src/providers/webvizio/runtime.js +3 -4
- package/src/providers/wecom_bot/smart-runtime.js +4 -5
- package/src/providers/wecom_mcp/runtime.js +3 -4
- package/src/providers/wejam_ai/runtime.js +3 -3
- package/src/providers/wolfram_alpha_api/runtime.js +3 -3
- package/src/providers/woocommerce/runtime.js +1 -1
- package/src/providers/woodpecker_co/executors.js +3 -4
- package/src/providers/woot/runtime.js +6 -6
- package/src/providers/workable/runtime.js +3 -3
- package/src/providers/workday/runtime.js +4 -4
- package/src/providers/workiom/runtime.js +2 -2
- package/src/providers/workiz/runtime.js +2 -2
- package/src/providers/workpath/executors.js +3 -4
- package/src/providers/worksnaps/executors.js +2 -2
- package/src/providers/y_gy/runtime.js +2 -2
- package/src/providers/zenscrape/runtime.js +3 -3
- package/src/providers/zep/runtime.js +4 -4
- package/src/providers/zeplin/runtime.js +2 -2
- package/src/providers/zhihu/executors.js +6 -6
- package/src/providers/zylvie/runtime.js +4 -4
- package/src/saas/saas-cleanup-service.d.ts +2 -0
- package/src/saas/saas-cleanup-service.js +2 -1
- package/src/saas/saas-execution-service.d.ts +1 -1
- package/src/server/actions/action-runner.js +1 -1
- package/src/server/api/auth.js +3 -0
- package/src/server/api/connection-routes.js +1 -1
- package/src/server/api/console-catalog-routes.js +1 -1
- package/src/server/api/console-oauth-routes.d.ts +3 -1
- package/src/server/api/console-oauth-routes.js +22 -9
- package/src/server/api/oauth-completion-page.d.ts +57 -0
- package/src/server/api/oauth-completion-page.js +135 -10
- package/src/server/api/openapi.d.ts +5 -0
- package/src/server/api/openapi.js +62 -2
- package/src/server/api/runtime-api.d.ts +2 -1
- package/src/server/api/runtime-app-routes.js +1 -1
- package/src/server/api/runtime-execution-routes.js +2 -1
- package/src/server/connect-app.d.ts +4 -0
- package/src/server/connect-app.js +14 -1
- package/src/server/connect-server.d.ts +6 -0
- package/src/server/connect-server.js +114 -4
- package/src/server/connector-runtime.d.ts +6 -8
- package/src/server/connector-runtime.js +8 -28
- package/src/server/proxy/proxy-runner.js +1 -1
- package/src/server/slack-event-verification.d.ts +37 -0
- package/src/server/slack-event-verification.js +91 -0
- package/src/server/storage/connection-request-store.d.ts +1 -1
- package/src/server/storage/connection-store.d.ts +1 -1
- package/src/server/storage/postgres/runtime-store.d.ts +1 -1
- package/src/server/storage/runtime-database.d.ts +1 -1
- package/src/server/storage/saas-project-store.d.ts +1 -1
- package/src/triggers/maintenance.d.ts +2 -0
- package/src/triggers/maintenance.js +2 -1
- package/src/triggers/sources/slack-signature.d.ts +10 -0
- package/src/triggers/sources/slack-signature.js +13 -0
- package/src/triggers/sources/slack.js +9 -11
- package/src/triggers/trigger-runner.js +1 -1
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CatalogStore } from "./catalog-store.ts";
|
|
2
|
+
import type { IConnectionStore, StoredConnection, StoredSaasConnection, SaasConnectionReference } from "./connection-store.ts";
|
|
2
3
|
import type { ProviderHttpDispatchOptions } from "./core/provider-http-dispatch.ts";
|
|
3
4
|
import type { AuthType, CredentialProfile, ResolvedCredential, RuntimeLogger } from "./core/types.ts";
|
|
4
5
|
import type { MarketplacePricing, MarketplaceService } from "./marketplace/marketplace-service.ts";
|
|
@@ -51,34 +52,6 @@ export interface ConnectionServiceOptions {
|
|
|
51
52
|
logger?: RuntimeLogger;
|
|
52
53
|
marketplace?: MarketplaceService;
|
|
53
54
|
}
|
|
54
|
-
export interface SaasConnectionReference {
|
|
55
|
-
managedProjectId: string;
|
|
56
|
-
providerConfigId: string;
|
|
57
|
-
externalUserId: string;
|
|
58
|
-
connectedAccountId: string;
|
|
59
|
-
localRequestId: string;
|
|
60
|
-
}
|
|
61
|
-
export interface StoredSaasConnection {
|
|
62
|
-
source: "saas";
|
|
63
|
-
credential?: never;
|
|
64
|
-
id: string;
|
|
65
|
-
revision: string;
|
|
66
|
-
service: string;
|
|
67
|
-
connectionName: string;
|
|
68
|
-
reference: SaasConnectionReference;
|
|
69
|
-
profile: CredentialProfile;
|
|
70
|
-
status: "active" | "reauth_required";
|
|
71
|
-
comment: string | null;
|
|
72
|
-
}
|
|
73
|
-
export type StoredConnection = StoredLocalConnection | StoredSaasConnection;
|
|
74
|
-
export interface StoredLocalConnection {
|
|
75
|
-
source?: "local";
|
|
76
|
-
id: string;
|
|
77
|
-
revision: string;
|
|
78
|
-
service: string;
|
|
79
|
-
connectionName: string;
|
|
80
|
-
credential: ResolvedCredential;
|
|
81
|
-
}
|
|
82
55
|
export interface DisconnectOptions {
|
|
83
56
|
/**
|
|
84
57
|
* `true` also revokes the OAuth grant at the provider once the credential is
|
|
@@ -111,18 +84,6 @@ interface SaasExecutionConnection {
|
|
|
111
84
|
summary: ManagedConnectionSummary;
|
|
112
85
|
reference: SaasConnectionReference;
|
|
113
86
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Storage contract for local provider connections.
|
|
116
|
-
*/
|
|
117
|
-
export interface IConnectionStore {
|
|
118
|
-
get(service: string, connectionName: string): Promise<StoredConnection | undefined>;
|
|
119
|
-
getRetirementGeneration(service: string, connectionName: string): Promise<string>;
|
|
120
|
-
setIfCurrentGeneration(service: string, connectionName: string, credential: ResolvedCredential, retirementGeneration: string): Promise<StoredLocalConnection | undefined>;
|
|
121
|
-
set(service: string, connectionName: string, credential: ResolvedCredential): Promise<StoredLocalConnection>;
|
|
122
|
-
updateCredential(input: StoredLocalConnection, refresh?: boolean): Promise<boolean>;
|
|
123
|
-
delete(service: string, connectionName: string): Promise<void>;
|
|
124
|
-
list(): Promise<StoredConnection[]>;
|
|
125
|
-
}
|
|
126
87
|
type OAuthCredential = Extract<ResolvedCredential, {
|
|
127
88
|
authType: "oauth2";
|
|
128
89
|
}>;
|
|
@@ -135,7 +96,7 @@ type OAuthCredential = Extract<ResolvedCredential, {
|
|
|
135
96
|
export declare class ConnectionService {
|
|
136
97
|
private readonly providerHttpDispatch?;
|
|
137
98
|
private readonly catalog;
|
|
138
|
-
private readonly
|
|
99
|
+
private readonly credentials;
|
|
139
100
|
private readonly oauthCredentials?;
|
|
140
101
|
private readonly providerLoader;
|
|
141
102
|
private readonly store;
|
|
@@ -208,8 +169,6 @@ export declare class ConnectionService {
|
|
|
208
169
|
private validateCustomCredential;
|
|
209
170
|
private validateOAuthCredential;
|
|
210
171
|
private createValidatorOptions;
|
|
211
|
-
private resolveOAuthCredential;
|
|
212
|
-
private refreshOAuthCredential;
|
|
213
172
|
private runCredentialValidator;
|
|
214
173
|
private assertNotCancelled;
|
|
215
174
|
private buildCredentialRuntimeData;
|
|
@@ -220,11 +179,4 @@ export declare class ConnectionService {
|
|
|
220
179
|
private createDefaultDisplayName;
|
|
221
180
|
}
|
|
222
181
|
export declare function normalizeConnectionName(value: string | undefined): string;
|
|
223
|
-
/**
|
|
224
|
-
* Error with a stable code suitable for HTTP responses.
|
|
225
|
-
*/
|
|
226
|
-
export declare class ConnectionError extends Error {
|
|
227
|
-
readonly code: string;
|
|
228
|
-
constructor(code: string, message: string);
|
|
229
|
-
}
|
|
230
182
|
export {};
|
|
@@ -1,32 +1,10 @@
|
|
|
1
|
+
import { ConnectionError } from "./connection-error.js";
|
|
1
2
|
import { normalizeCredentialValues } from "./core/credential-fields.js";
|
|
2
3
|
import { apiKeyCredentialFields } from "./core/provider-setup.js";
|
|
4
|
+
import { CredentialResolver, isOAuthCredentialExpired } from "./credential-resolver.js";
|
|
3
5
|
import { providerFetch, ProviderDispatchRequestError, withProviderHttpDispatchResult, } from "./providers/provider-runtime.js";
|
|
4
6
|
export const defaultConnectionName = "default";
|
|
5
7
|
const connectionNamePattern = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
6
|
-
const OAUTH_REFRESH_PERSIST_ATTEMPTS = 3;
|
|
7
|
-
/**
|
|
8
|
-
* Lays a refresh result onto the connection's current credential. A refresh owns the token
|
|
9
|
-
* fields and the metadata keys it changed; everything else on `current` belongs to whoever
|
|
10
|
-
* bumped the revision and is kept.
|
|
11
|
-
*/
|
|
12
|
-
function mergeRefreshedOAuthCredential(current, spent, refreshed) {
|
|
13
|
-
const metadata = { ...current.metadata };
|
|
14
|
-
for (const [key, value] of Object.entries(refreshed.metadata)) {
|
|
15
|
-
if (JSON.stringify(value) !== JSON.stringify(spent.metadata[key]))
|
|
16
|
-
metadata[key] = value;
|
|
17
|
-
}
|
|
18
|
-
// A successful refresh proves the authorization is live, so a concurrent refusal's mark is stale.
|
|
19
|
-
delete metadata.oauthReauthRequired;
|
|
20
|
-
return {
|
|
21
|
-
...current,
|
|
22
|
-
accessToken: refreshed.accessToken,
|
|
23
|
-
tokenType: refreshed.tokenType,
|
|
24
|
-
expiresAt: refreshed.expiresAt,
|
|
25
|
-
refreshToken: refreshed.refreshToken,
|
|
26
|
-
providerSecret: refreshed.providerSecret,
|
|
27
|
-
metadata,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
8
|
/**
|
|
31
9
|
* Coordinates local provider connection state.
|
|
32
10
|
*
|
|
@@ -36,7 +14,7 @@ function mergeRefreshedOAuthCredential(current, spent, refreshed) {
|
|
|
36
14
|
export class ConnectionService {
|
|
37
15
|
providerHttpDispatch;
|
|
38
16
|
catalog;
|
|
39
|
-
|
|
17
|
+
credentials;
|
|
40
18
|
oauthCredentials;
|
|
41
19
|
providerLoader;
|
|
42
20
|
store;
|
|
@@ -48,6 +26,7 @@ export class ConnectionService {
|
|
|
48
26
|
this.oauthCredentials = input.oauthCredentials;
|
|
49
27
|
this.providerLoader = input.providerLoader;
|
|
50
28
|
this.store = input.store;
|
|
29
|
+
this.credentials = new CredentialResolver(input);
|
|
51
30
|
this.logger = input.logger;
|
|
52
31
|
this.marketplace = input.marketplace;
|
|
53
32
|
}
|
|
@@ -138,10 +117,7 @@ export class ConnectionService {
|
|
|
138
117
|
}
|
|
139
118
|
if (stored?.source === "saas")
|
|
140
119
|
return { kind: "saas", summary: this.createManagedConnectionSummary(stored), reference: stored.reference };
|
|
141
|
-
let credential = stored
|
|
142
|
-
if (stored?.credential.authType === "oauth2") {
|
|
143
|
-
credential = await this.resolveOAuthCredential(stored, stored.credential);
|
|
144
|
-
}
|
|
120
|
+
let credential = stored ? await this.credentials.resolve(stored) : undefined;
|
|
145
121
|
credential ??= this.supportsAuth(provider, "no_auth") ? { authType: "no_auth" } : undefined;
|
|
146
122
|
const summary = stored
|
|
147
123
|
? this.createConfiguredConnectionSummary(provider, stored.id, name, credential)
|
|
@@ -161,9 +137,7 @@ export class ConnectionService {
|
|
|
161
137
|
if (stored?.source === "saas")
|
|
162
138
|
throw new ConnectionError("unsupported_auth_type", "SaaS credentials are not available locally.");
|
|
163
139
|
if (stored) {
|
|
164
|
-
return
|
|
165
|
-
? await this.resolveOAuthCredential(stored, stored.credential)
|
|
166
|
-
: stored.credential;
|
|
140
|
+
return this.credentials.resolve(stored);
|
|
167
141
|
}
|
|
168
142
|
if (connectionName && !this.supportsAuth(provider, "no_auth")) {
|
|
169
143
|
throw new ConnectionError("connection_not_found", `${service} connection not found: ${name}.`);
|
|
@@ -514,87 +488,6 @@ export class ConnectionService {
|
|
|
514
488
|
signal,
|
|
515
489
|
};
|
|
516
490
|
}
|
|
517
|
-
async resolveOAuthCredential(connection, credential) {
|
|
518
|
-
const service = connection.service;
|
|
519
|
-
if (credential.metadata.oauthReauthRequired === true) {
|
|
520
|
-
throw new ConnectionError("oauth_reauth_required", `OAuth authorization is no longer valid. Reconnect ${service}.`);
|
|
521
|
-
}
|
|
522
|
-
if (!isOAuthCredentialExpired(credential)) {
|
|
523
|
-
return credential;
|
|
524
|
-
}
|
|
525
|
-
if (!credential.refreshToken) {
|
|
526
|
-
throw new ConnectionError("oauth_token_expired", `${service} OAuth access token expired and no refresh token is available. Reconnect ${service}.`);
|
|
527
|
-
}
|
|
528
|
-
if (!this.oauthCredentials) {
|
|
529
|
-
throw new ConnectionError("oauth_refresh_unavailable", `${service} OAuth access token expired and this runtime cannot refresh it.`);
|
|
530
|
-
}
|
|
531
|
-
// Single-flight on the refresh token being spent, not the row revision: a single-use
|
|
532
|
-
// (rotating) refresh token must reach the provider once even when an unrelated write
|
|
533
|
-
// bumps the revision mid-refresh. A new authorization must refresh independently,
|
|
534
|
-
// even when the provider reuses the same refresh token across reconnects.
|
|
535
|
-
const refreshKey = JSON.stringify([
|
|
536
|
-
connection.id,
|
|
537
|
-
credential.refreshToken,
|
|
538
|
-
credential.metadata.oauthAuthorizationId,
|
|
539
|
-
]);
|
|
540
|
-
const currentRefresh = this.oauthCredentialRefreshes.get(refreshKey);
|
|
541
|
-
if (currentRefresh) {
|
|
542
|
-
return currentRefresh;
|
|
543
|
-
}
|
|
544
|
-
const refresh = this.refreshOAuthCredential(connection, credential, this.oauthCredentials);
|
|
545
|
-
this.oauthCredentialRefreshes.set(refreshKey, refresh);
|
|
546
|
-
try {
|
|
547
|
-
return await refresh;
|
|
548
|
-
}
|
|
549
|
-
finally {
|
|
550
|
-
if (this.oauthCredentialRefreshes.get(refreshKey) === refresh) {
|
|
551
|
-
this.oauthCredentialRefreshes.delete(refreshKey);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
async refreshOAuthCredential(connection, credential, refresher) {
|
|
556
|
-
const { id, revision, service, connectionName } = connection;
|
|
557
|
-
let nextCredential;
|
|
558
|
-
try {
|
|
559
|
-
nextCredential = await withProviderHttpDispatchResult({ operation: "oauth", service, connectionId: id, connectionName }, () => refresher.refresh(service, credential), this.providerHttpDispatch);
|
|
560
|
-
}
|
|
561
|
-
catch (error) {
|
|
562
|
-
if (error instanceof ConnectionError && error.code === "oauth_reauth_required") {
|
|
563
|
-
// The revision fence prevents a late refusal from marking a replacement authorization as expired.
|
|
564
|
-
await this.store.updateCredential({
|
|
565
|
-
id,
|
|
566
|
-
revision,
|
|
567
|
-
service,
|
|
568
|
-
connectionName,
|
|
569
|
-
credential: { ...credential, metadata: { ...credential.metadata, oauthReauthRequired: true } },
|
|
570
|
-
}, true);
|
|
571
|
-
}
|
|
572
|
-
throw error;
|
|
573
|
-
}
|
|
574
|
-
// The provider has now spent the old refresh token. With rotating single-use refresh
|
|
575
|
-
// tokens, discarding `nextCredential` loses the connection for good, so a lost
|
|
576
|
-
// revision race re-reads the row and lands the refreshed token fields on the latest
|
|
577
|
-
// revision, as long as that row still holds the credential this refresh spent.
|
|
578
|
-
let target = { ...connection, source: "local", credential: nextCredential };
|
|
579
|
-
for (let attempt = 0; attempt < OAUTH_REFRESH_PERSIST_ATTEMPTS; attempt++) {
|
|
580
|
-
if (await this.store.updateCredential(target, true))
|
|
581
|
-
return target.credential;
|
|
582
|
-
const current = await this.store.get(service, connectionName);
|
|
583
|
-
if (current?.source === "saas" ||
|
|
584
|
-
current?.id !== id ||
|
|
585
|
-
current.credential.authType !== "oauth2" ||
|
|
586
|
-
current.credential.refreshToken !== credential.refreshToken ||
|
|
587
|
-
current.credential.metadata.oauthAuthorizationId !== credential.metadata.oauthAuthorizationId) {
|
|
588
|
-
// Deleted, converted, reconnected, or already rotated elsewhere: never overwrite it.
|
|
589
|
-
break;
|
|
590
|
-
}
|
|
591
|
-
target = {
|
|
592
|
-
...current,
|
|
593
|
-
credential: mergeRefreshedOAuthCredential(current.credential, credential, nextCredential),
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
throw new ConnectionError("connection_not_found", `${service} connection changed while its OAuth credential was refreshing. Retry the action.`);
|
|
597
|
-
}
|
|
598
491
|
async runCredentialValidator(service, validate, signal) {
|
|
599
492
|
this.assertNotCancelled(signal);
|
|
600
493
|
try {
|
|
@@ -686,13 +579,6 @@ export class ConnectionService {
|
|
|
686
579
|
return `${provider.displayName} ${authType === "api_key" ? "API Key" : "Credential"}`;
|
|
687
580
|
}
|
|
688
581
|
}
|
|
689
|
-
function isOAuthCredentialExpired(credential) {
|
|
690
|
-
if (!credential.expiresAt) {
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
const expiresAt = Date.parse(credential.expiresAt);
|
|
694
|
-
return Number.isFinite(expiresAt) && expiresAt <= Date.now() + 60_000;
|
|
695
|
-
}
|
|
696
582
|
export function normalizeConnectionName(value) {
|
|
697
583
|
const name = value?.trim() || defaultConnectionName;
|
|
698
584
|
if (!connectionNamePattern.test(name)) {
|
|
@@ -710,16 +596,6 @@ function readLegacyString(metadata, key) {
|
|
|
710
596
|
const value = metadata?.[key];
|
|
711
597
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
712
598
|
}
|
|
713
|
-
/**
|
|
714
|
-
* Error with a stable code suitable for HTTP responses.
|
|
715
|
-
*/
|
|
716
|
-
export class ConnectionError extends Error {
|
|
717
|
-
code;
|
|
718
|
-
constructor(code, message) {
|
|
719
|
-
super(message);
|
|
720
|
-
this.code = code;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
599
|
function describeError(error) {
|
|
724
600
|
return error instanceof Error ? error.message : String(error);
|
|
725
601
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CredentialProfile, ResolvedCredential } from "./core/types.ts";
|
|
2
|
+
export interface SaasConnectionReference {
|
|
3
|
+
managedProjectId: string;
|
|
4
|
+
providerConfigId: string;
|
|
5
|
+
externalUserId: string;
|
|
6
|
+
connectedAccountId: string;
|
|
7
|
+
localRequestId: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StoredSaasConnection {
|
|
10
|
+
source: "saas";
|
|
11
|
+
credential?: never;
|
|
12
|
+
id: string;
|
|
13
|
+
revision: string;
|
|
14
|
+
service: string;
|
|
15
|
+
connectionName: string;
|
|
16
|
+
reference: SaasConnectionReference;
|
|
17
|
+
profile: CredentialProfile;
|
|
18
|
+
status: "active" | "reauth_required";
|
|
19
|
+
comment: string | null;
|
|
20
|
+
}
|
|
21
|
+
export type StoredConnection = StoredLocalConnection | StoredSaasConnection;
|
|
22
|
+
export interface StoredLocalConnection {
|
|
23
|
+
source?: "local";
|
|
24
|
+
id: string;
|
|
25
|
+
revision: string;
|
|
26
|
+
service: string;
|
|
27
|
+
connectionName: string;
|
|
28
|
+
credential: ResolvedCredential;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Storage contract for local and SaaS provider connections.
|
|
32
|
+
*/
|
|
33
|
+
export interface IConnectionStore {
|
|
34
|
+
get(service: string, connectionName: string): Promise<StoredConnection | undefined>;
|
|
35
|
+
getRetirementGeneration(service: string, connectionName: string): Promise<string>;
|
|
36
|
+
setIfCurrentGeneration(service: string, connectionName: string, credential: ResolvedCredential, retirementGeneration: string): Promise<StoredLocalConnection | undefined>;
|
|
37
|
+
set(service: string, connectionName: string, credential: ResolvedCredential): Promise<StoredLocalConnection>;
|
|
38
|
+
updateCredential(input: StoredLocalConnection, refresh?: boolean): Promise<boolean>;
|
|
39
|
+
delete(service: string, connectionName: string): Promise<void>;
|
|
40
|
+
list(): Promise<StoredConnection[]>;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GuardedHttpDispatcher } from "./provider-http-dispatch.ts";
|
|
2
|
+
import type { ProviderNetworkPolicy } from "./provider-network-policy.ts";
|
|
2
3
|
/**
|
|
3
4
|
* Single resolved address returned by a DNS lookup, mirroring the shape of
|
|
4
5
|
* `node:dns` `lookup(hostname, { all: true })` entries.
|
|
@@ -13,6 +14,8 @@ export interface ResolvedAddress {
|
|
|
13
14
|
*/
|
|
14
15
|
export type GuardedFetchDnsLookup = (hostname: string) => Promise<ResolvedAddress[]>;
|
|
15
16
|
export interface GuardedFetchOptions {
|
|
17
|
+
/** Bind runtime policy; private targets still require the transport's allowPrivateNetwork opt-in. */
|
|
18
|
+
network?: ProviderNetworkPolicy;
|
|
16
19
|
/** Optional dispatcher at the screened raw-transport seam; every redirect hop passes through it. */
|
|
17
20
|
dispatchAttempt?: GuardedHttpDispatcher;
|
|
18
21
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withProviderNetworkPolicy } from "./provider-network-policy.js";
|
|
1
2
|
import { assertPublicHttpUrl, classifyIpAddress, isEgressTrustedHost, isIpAddress, isIpv4Address } from "./request.js";
|
|
2
3
|
// Match the platform default for `redirect: "follow"` (undici/browsers follow up
|
|
3
4
|
// to 20 hops) so wrapping the transport does not fail legitimate long redirect
|
|
@@ -77,6 +78,8 @@ export const crossOriginSafeHeaders = new Set([
|
|
|
77
78
|
const bodyHeaders = ["content-encoding", "content-language", "content-length", "content-location", "content-type"];
|
|
78
79
|
/** Base transport behind each guarded fetch (undefined = global fetch) so re-wrapping never stacks guards. */
|
|
79
80
|
const guardedFetchBases = new WeakMap();
|
|
81
|
+
/** Preserve an explicitly bound runtime policy when a provider rewraps its transport. */
|
|
82
|
+
const guardedFetchPolicies = new WeakMap();
|
|
80
83
|
/** Retain admission when a caller replaces the egress policy without stacking guards. */
|
|
81
84
|
const guardedFetchDispatchers = new WeakMap();
|
|
82
85
|
let defaultLookupOverridden = false;
|
|
@@ -136,10 +139,11 @@ export function unwrapGuardedFetch(fetcher) {
|
|
|
136
139
|
*/
|
|
137
140
|
export function createGuardedFetch(options = {}) {
|
|
138
141
|
const baseFetch = unwrapGuardedFetch(options.fetch);
|
|
142
|
+
const network = options.network ?? (options.fetch && guardedFetchPolicies.get(options.fetch));
|
|
139
143
|
const dispatchAttempt = options.dispatchAttempt ?? (options.fetch && guardedFetchDispatchers.get(options.fetch));
|
|
140
144
|
const createError = options.createError ?? ((message) => new TypeError(message));
|
|
141
145
|
const maxRedirects = options.maxRedirects ?? defaultMaxRedirects;
|
|
142
|
-
const
|
|
146
|
+
const performFetch = (async (input, init) => {
|
|
143
147
|
const transport = baseFetch ?? globalThis.fetch;
|
|
144
148
|
const requestId = dispatchAttempt ? crypto.randomUUID() : "";
|
|
145
149
|
let redirectHop = 0;
|
|
@@ -251,6 +255,9 @@ export function createGuardedFetch(options = {}) {
|
|
|
251
255
|
url = guardedNext;
|
|
252
256
|
}
|
|
253
257
|
});
|
|
258
|
+
const guardedFetch = (network ? (input, init) => withProviderNetworkPolicy(network, () => performFetch(input, init)) : performFetch);
|
|
259
|
+
if (network)
|
|
260
|
+
guardedFetchPolicies.set(guardedFetch, network);
|
|
254
261
|
guardedFetchBases.set(guardedFetch, baseFetch);
|
|
255
262
|
guardedFetchDispatchers.set(guardedFetch, dispatchAttempt);
|
|
256
263
|
return guardedFetch;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Runtime-owned egress permissions; never populate them from provider input. */
|
|
2
|
+
export interface ProviderNetworkPolicy {
|
|
3
|
+
/**
|
|
4
|
+
* Runtime permission read by isPrivateNetworkAccessAllowed(). Binding this policy
|
|
5
|
+
* alone does not relax fetch targets: the provider must also opt in through its
|
|
6
|
+
* transport's allowPrivateNetwork callback. Reserved targets stay blocked.
|
|
7
|
+
*/
|
|
8
|
+
readonly allowPrivateNetwork?: boolean;
|
|
9
|
+
/** Hosts whose DNS answers may use private or VPN-mapped ranges. */
|
|
10
|
+
readonly trustedHosts?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
/** The active runtime's policy, or public-only access outside a runtime. */
|
|
13
|
+
export declare function getProviderNetworkPolicy(): ProviderNetworkPolicy;
|
|
14
|
+
/** Bind policy to asynchronous work, including provider callbacks and non-HTTP transports. */
|
|
15
|
+
export declare function withProviderNetworkPolicy<T>(policy: ProviderNetworkPolicy, work: () => T): T;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const scopes = new AsyncLocalStorage();
|
|
3
|
+
const publicNetworkPolicy = Object.freeze({});
|
|
4
|
+
/** The active runtime's policy, or public-only access outside a runtime. */
|
|
5
|
+
export function getProviderNetworkPolicy() {
|
|
6
|
+
return scopes.getStore() ?? publicNetworkPolicy;
|
|
7
|
+
}
|
|
8
|
+
/** Bind policy to asynchronous work, including provider callbacks and non-HTTP transports. */
|
|
9
|
+
export function withProviderNetworkPolicy(policy, work) {
|
|
10
|
+
return scopes.run(policy, work);
|
|
11
|
+
}
|
package/src/core/request.d.ts
CHANGED
|
@@ -65,25 +65,29 @@ export interface PublicHttpUrlOptions {
|
|
|
65
65
|
/** Allow RFC 1918, shared-address-space, and private hostname targets while retaining reserved-target guards. */
|
|
66
66
|
allowPrivateNetwork?: boolean;
|
|
67
67
|
}
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Read the active asynchronous runtime context’s private-network permission.
|
|
70
|
+
* Self-hosted providers opt into this permission through their URL and transport guards.
|
|
71
|
+
*
|
|
72
|
+
* Off by default so a shared/multi-tenant runtime keeps a public-only SSRF guard
|
|
73
|
+
* and a tenant cannot turn a self-hosted connection into an SSRF pivot into the
|
|
74
|
+
* operator's internal network. Single-tenant, self-hosted operators enable it
|
|
75
|
+
* through the `OOMOL_CONNECT_ALLOW_PRIVATE_NETWORK` environment variable.
|
|
76
|
+
*
|
|
77
|
+
* Even when enabled, reserved, loopback, link-local, cloud-metadata, multicast,
|
|
78
|
+
* and IPv6 targets remain blocked by {@link assertPublicHttpUrl}.
|
|
79
|
+
*/
|
|
71
80
|
export declare function isPrivateNetworkAccessAllowed(): boolean;
|
|
72
81
|
/** Parse the `OOMOL_CONNECT_ALLOW_PRIVATE_NETWORK` flag; only explicit truthy values enable it. */
|
|
73
82
|
export declare function parsePrivateNetworkAccessFlag(value: string | undefined): boolean;
|
|
74
83
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*/
|
|
78
|
-
export declare function setEgressTrustedHosts(hosts: readonly string[]): void;
|
|
79
|
-
/**
|
|
80
|
-
* Whether `hostname` may resolve through private or VPN-mapped ranges.
|
|
84
|
+
* Whether the active runtime trusts this hostname's private or VPN-mapped DNS answers.
|
|
85
|
+
* No hosts are trusted outside a configured runtime context.
|
|
81
86
|
*
|
|
82
|
-
* An entry starting with `.` matches
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* {@link assertPublicHttpUrl} and this list does not reach it.
|
|
87
|
+
* An entry starting with `.` matches the domain and its subdomains; other entries
|
|
88
|
+
* match exactly. The exception applies only to DNS answers, not literal IP URLs.
|
|
89
|
+
* It supports corporate VPNs that map public domains into private or benchmark
|
|
90
|
+
* ranges. Loopback, link-local, cloud-metadata and other unsafe addresses remain blocked.
|
|
87
91
|
*/
|
|
88
92
|
export declare function isEgressTrustedHost(hostname: string): boolean;
|
|
89
93
|
/**
|
package/src/core/request.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getProviderNetworkPolicy } from "./provider-network-policy.js";
|
|
1
2
|
/**
|
|
2
3
|
* Convert defined scalar values into URL query strings.
|
|
3
4
|
*
|
|
@@ -250,8 +251,8 @@ const ipv4EmbeddedIpv6Cidrs = [
|
|
|
250
251
|
[ipv6ToBytes("2002::"), 16, 2],
|
|
251
252
|
];
|
|
252
253
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
254
|
+
* Read the active asynchronous runtime context’s private-network permission.
|
|
255
|
+
* Self-hosted providers opt into this permission through their URL and transport guards.
|
|
255
256
|
*
|
|
256
257
|
* Off by default so a shared/multi-tenant runtime keeps a public-only SSRF guard
|
|
257
258
|
* and a tenant cannot turn a self-hosted connection into an SSRF pivot into the
|
|
@@ -261,14 +262,8 @@ const ipv4EmbeddedIpv6Cidrs = [
|
|
|
261
262
|
* Even when enabled, reserved, loopback, link-local, cloud-metadata, multicast,
|
|
262
263
|
* and IPv6 targets remain blocked by {@link assertPublicHttpUrl}.
|
|
263
264
|
*/
|
|
264
|
-
let privateNetworkAccessAllowed = false;
|
|
265
|
-
/** Configure whether opted-in providers may target private networks (called once at deployment bootstrap). */
|
|
266
|
-
export function setPrivateNetworkAccessAllowed(allowed) {
|
|
267
|
-
privateNetworkAccessAllowed = allowed;
|
|
268
|
-
}
|
|
269
|
-
/** Whether the current deployment allows opted-in providers to target private networks. */
|
|
270
265
|
export function isPrivateNetworkAccessAllowed() {
|
|
271
|
-
return
|
|
266
|
+
return getProviderNetworkPolicy().allowPrivateNetwork ?? false;
|
|
272
267
|
}
|
|
273
268
|
/** Parse the `OOMOL_CONNECT_ALLOW_PRIVATE_NETWORK` flag; only explicit truthy values enable it. */
|
|
274
269
|
export function parsePrivateNetworkAccessFlag(value) {
|
|
@@ -279,35 +274,16 @@ export function parsePrivateNetworkAccessFlag(value) {
|
|
|
279
274
|
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
|
280
275
|
}
|
|
281
276
|
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* Zero-trust corporate VPNs (aTrust / EasyConnect class) resolve public SaaS
|
|
285
|
-
* domains into a reserved range — commonly `198.18.0.0/15` — and tunnel the
|
|
286
|
-
* traffic from there, so on those networks a reserved address is the normal
|
|
287
|
-
* path to the real service rather than an SSRF target. Reserved ranges are
|
|
288
|
-
* checked unconditionally, so {@link isPrivateNetworkAccessAllowed} cannot open
|
|
289
|
-
* them, and there is otherwise no way for an operator to say "this host is
|
|
290
|
-
* reachable through my VPN". Loopback, link-local, cloud-metadata, multicast,
|
|
291
|
-
* and other unsafe special-use ranges remain blocked. Empty by default.
|
|
292
|
-
*/
|
|
293
|
-
let egressTrustedHosts = [];
|
|
294
|
-
/**
|
|
295
|
-
* Configure the hosts that may resolve through private or VPN-mapped ranges
|
|
296
|
-
* (called once at deployment bootstrap).
|
|
297
|
-
*/
|
|
298
|
-
export function setEgressTrustedHosts(hosts) {
|
|
299
|
-
egressTrustedHosts = hosts;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Whether `hostname` may resolve through private or VPN-mapped ranges.
|
|
277
|
+
* Whether the active runtime trusts this hostname's private or VPN-mapped DNS answers.
|
|
278
|
+
* No hosts are trusted outside a configured runtime context.
|
|
303
279
|
*
|
|
304
|
-
* An entry starting with `.` matches
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
* {@link assertPublicHttpUrl} and this list does not reach it.
|
|
280
|
+
* An entry starting with `.` matches the domain and its subdomains; other entries
|
|
281
|
+
* match exactly. The exception applies only to DNS answers, not literal IP URLs.
|
|
282
|
+
* It supports corporate VPNs that map public domains into private or benchmark
|
|
283
|
+
* ranges. Loopback, link-local, cloud-metadata and other unsafe addresses remain blocked.
|
|
309
284
|
*/
|
|
310
285
|
export function isEgressTrustedHost(hostname) {
|
|
286
|
+
const egressTrustedHosts = getProviderNetworkPolicy().trustedHosts ?? [];
|
|
311
287
|
if (egressTrustedHosts.length === 0) {
|
|
312
288
|
return false;
|
|
313
289
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { IConnectionStore, StoredLocalConnection } from "./connection-store.ts";
|
|
2
|
+
import type { ProviderHttpDispatchOptions } from "./core/provider-http-dispatch.ts";
|
|
3
|
+
import type { ResolvedCredential } from "./core/types.ts";
|
|
4
|
+
import type { IOAuthCredentialRefresher } from "./oauth/oauth-credential-refresh-service.ts";
|
|
5
|
+
interface CredentialResolverOptions {
|
|
6
|
+
store: IConnectionStore;
|
|
7
|
+
oauthCredentials?: IOAuthCredentialRefresher;
|
|
8
|
+
providerHttpDispatch?: ProviderHttpDispatchOptions;
|
|
9
|
+
}
|
|
10
|
+
/** Resolves stored credentials and owns refresh coalescing and revision-safe persistence. */
|
|
11
|
+
export declare class CredentialResolver {
|
|
12
|
+
private readonly store;
|
|
13
|
+
private readonly oauthCredentials?;
|
|
14
|
+
private readonly providerHttpDispatch?;
|
|
15
|
+
private readonly oauthCredentialRefreshes;
|
|
16
|
+
constructor(options: CredentialResolverOptions);
|
|
17
|
+
resolve(connection: StoredLocalConnection): Promise<ResolvedCredential>;
|
|
18
|
+
private resolveOAuthCredential;
|
|
19
|
+
private refreshOAuthCredential;
|
|
20
|
+
}
|
|
21
|
+
export declare function isOAuthCredentialExpired(credential: Extract<ResolvedCredential, {
|
|
22
|
+
authType: "oauth2";
|
|
23
|
+
}>): boolean;
|
|
24
|
+
export {};
|