runline 0.33.0 → 0.34.0
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/auth/oauth2.d.ts +7 -1
- package/dist/auth/oauth2.js +10 -0
- package/dist/auth/token.d.ts +1 -0
- package/dist/auth/token.js +19 -1
- package/dist/auth/types.d.ts +22 -1
- package/dist/core/engine.d.ts +7 -0
- package/dist/core/engine.js +9 -0
- package/dist/credentials/policy.d.ts +53 -1
- package/dist/credentials/policy.js +146 -6
- package/dist/credentials/registry.d.ts +9 -0
- package/dist/credentials/registry.js +179 -22
- package/dist/credentials/transport.d.ts +48 -2
- package/dist/credentials/transport.js +248 -70
- package/dist/credentials/types.d.ts +167 -10
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/plugin/api.d.ts +7 -0
- package/dist/plugin/api.js +7 -0
- package/dist/plugin/types.d.ts +12 -0
- package/dist/plugins/_shared/credentialAdapter.js +79 -15
- package/dist/plugins/_shared/credentials.js +389 -0
- package/dist/plugins/_shared/googleAuth.js +9 -40
- package/dist/plugins/_shared/googleCredentials.js +28 -7
- package/dist/plugins/_shared/microsoftAuth.js +13 -44
- package/dist/plugins/_shared/microsoftCredentials.js +30 -8
- package/dist/plugins/_shared/provider.js +2 -14
- package/dist/plugins/_shared/shiftCloud.js +19 -55
- package/dist/plugins/_shared/shiftCredentials.js +83 -0
- package/dist/plugins/actionNetwork/src/credentials.js +14 -0
- package/dist/plugins/actionNetwork/src/index.js +39 -50
- package/dist/plugins/activeCampaign/src/credentials.js +22 -0
- package/dist/plugins/activeCampaign/src/index.js +61 -132
- package/dist/plugins/adalo/src/credentials.js +16 -0
- package/dist/plugins/adalo/src/index.js +19 -43
- package/dist/plugins/affinity/src/credentials.js +19 -0
- package/dist/plugins/affinity/src/index.js +29 -54
- package/dist/plugins/agileCrm/src/credentials.js +16 -0
- package/dist/plugins/agileCrm/src/index.js +46 -112
- package/dist/plugins/airtable/src/credentials.js +19 -0
- package/dist/plugins/airtable/src/index.js +37 -50
- package/dist/plugins/airtop/src/credentials.js +20 -0
- package/dist/plugins/airtop/src/index.js +51 -75
- package/dist/plugins/apiTemplateIo/src/credentials.js +19 -0
- package/dist/plugins/apiTemplateIo/src/index.js +14 -31
- package/dist/plugins/asana/src/credentials.js +19 -0
- package/dist/plugins/asana/src/index.js +51 -72
- package/dist/plugins/autopilot/src/credentials.js +19 -0
- package/dist/plugins/autopilot/src/index.js +38 -45
- package/dist/plugins/bambooHr/src/credentials.js +16 -0
- package/dist/plugins/bambooHr/src/index.js +41 -67
- package/dist/plugins/bannerbear/src/credentials.js +19 -0
- package/dist/plugins/bannerbear/src/index.js +15 -27
- package/dist/plugins/baserow/src/credentials.js +17 -0
- package/dist/plugins/baserow/src/index.js +23 -49
- package/dist/plugins/beeminder/src/credentials.js +19 -0
- package/dist/plugins/beeminder/src/index.js +32 -54
- package/dist/plugins/bitly/src/credentials.js +19 -0
- package/dist/plugins/bitly/src/index.js +12 -26
- package/dist/plugins/bitwarden/src/credentials.js +62 -0
- package/dist/plugins/bitwarden/src/index.js +34 -80
- package/dist/plugins/box/src/credentials.js +19 -0
- package/dist/plugins/box/src/index.js +24 -49
- package/dist/plugins/brandfetch/src/credentials.js +13 -0
- package/dist/plugins/brandfetch/src/index.js +12 -17
- package/dist/plugins/brevo/src/credentials.js +19 -0
- package/dist/plugins/brevo/src/index.js +30 -51
- package/dist/plugins/bubble/src/credentials.js +28 -0
- package/dist/plugins/bubble/src/index.js +29 -65
- package/dist/plugins/chargebee/src/credentials.js +16 -0
- package/dist/plugins/chargebee/src/index.js +15 -45
- package/dist/plugins/circleci/src/credentials.js +19 -0
- package/dist/plugins/circleci/src/index.js +19 -39
- package/dist/plugins/ciscoWebex/src/credentials.js +19 -0
- package/dist/plugins/ciscoWebex/src/index.js +43 -61
- package/dist/plugins/clearbit/src/credentials.js +22 -0
- package/dist/plugins/clearbit/src/index.js +11 -21
- package/dist/plugins/clickup/src/credentials.js +19 -0
- package/dist/plugins/clickup/src/index.js +85 -117
- package/dist/plugins/clockify/src/credentials.js +19 -0
- package/dist/plugins/clockify/src/index.js +46 -61
- package/dist/plugins/cloudflare/src/credentials.js +19 -0
- package/dist/plugins/cloudflare/src/index.js +19 -34
- package/dist/plugins/cockpit/src/credentials.js +17 -0
- package/dist/plugins/cockpit/src/index.js +18 -31
- package/dist/plugins/coda/src/credentials.js +19 -0
- package/dist/plugins/coda/src/index.js +33 -50
- package/dist/plugins/coingecko/src/credentials.js +20 -0
- package/dist/plugins/coingecko/src/index.js +24 -34
- package/dist/plugins/contentful/src/credentials.js +26 -0
- package/dist/plugins/contentful/src/index.js +19 -40
- package/dist/plugins/convertkit/src/credentials.js +26 -0
- package/dist/plugins/convertkit/src/index.js +27 -45
- package/dist/plugins/copper/src/credentials.js +17 -0
- package/dist/plugins/copper/src/index.js +25 -47
- package/dist/plugins/cortex/src/credentials.js +28 -0
- package/dist/plugins/cortex/src/index.js +26 -49
- package/dist/plugins/currents/src/credentials.js +19 -0
- package/dist/plugins/currents/src/index.js +46 -59
- package/dist/plugins/customerIo/src/credentials.js +52 -0
- package/dist/plugins/customerIo/src/index.js +30 -58
- package/dist/plugins/databricks/src/credentials.js +13 -0
- package/dist/plugins/databricks/src/index.js +51 -103
- package/dist/plugins/deepl/src/credentials.js +19 -0
- package/dist/plugins/deepl/src/index.js +13 -39
- package/dist/plugins/demio/src/credentials.js +26 -0
- package/dist/plugins/demio/src/index.js +17 -41
- package/dist/plugins/dhl/src/credentials.js +13 -0
- package/dist/plugins/dhl/src/index.js +8 -19
- package/dist/plugins/discord/src/credentials.js +19 -0
- package/dist/plugins/discord/src/index.js +30 -58
- package/dist/plugins/discourse/src/credentials.js +18 -0
- package/dist/plugins/discourse/src/index.js +36 -53
- package/dist/plugins/disqus/src/credentials.js +13 -0
- package/dist/plugins/disqus/src/index.js +14 -32
- package/dist/plugins/drift/src/credentials.js +13 -0
- package/dist/plugins/drift/src/index.js +16 -26
- package/dist/plugins/dropbox/src/credentials.js +13 -0
- package/dist/plugins/dropbox/src/index.js +23 -30
- package/dist/plugins/dropcontact/src/credentials.js +13 -0
- package/dist/plugins/dropcontact/src/index.js +13 -18
- package/dist/plugins/egoi/src/credentials.js +19 -0
- package/dist/plugins/egoi/src/index.js +23 -38
- package/dist/plugins/elasticsearch/src/credentials.js +18 -0
- package/dist/plugins/elasticsearch/src/index.js +27 -48
- package/dist/plugins/elevenlabs/src/credentials.js +30 -0
- package/dist/plugins/elevenlabs/src/index.js +4 -1
- package/dist/plugins/elevenlabs/src/schemas.js +2 -1
- package/dist/plugins/elevenlabs/src/shared.js +74 -35
- package/dist/plugins/elevenlabs/src/workflows.js +2 -2
- package/dist/plugins/emelia/src/credentials.js +14 -0
- package/dist/plugins/emelia/src/index.js +19 -23
- package/dist/plugins/erpnext/src/credentials.js +27 -0
- package/dist/plugins/erpnext/src/index.js +21 -42
- package/dist/plugins/facebookGraph/src/credentials.js +20 -0
- package/dist/plugins/facebookGraph/src/index.js +39 -37
- package/dist/plugins/fal/src/credentials.js +14 -0
- package/dist/plugins/fal/src/index.js +4 -2
- package/dist/plugins/fal/src/shared.js +58 -63
- package/dist/plugins/freshdesk/src/credentials.js +20 -0
- package/dist/plugins/freshdesk/src/index.js +25 -46
- package/dist/plugins/freshservice/src/credentials.js +16 -0
- package/dist/plugins/freshservice/src/index.js +37 -58
- package/dist/plugins/freshworksCrm/src/credentials.js +16 -0
- package/dist/plugins/freshworksCrm/src/index.js +20 -39
- package/dist/plugins/getresponse/src/credentials.js +22 -0
- package/dist/plugins/getresponse/src/index.js +20 -32
- package/dist/plugins/gett/src/credentials.js +64 -0
- package/dist/plugins/gett/src/index.js +11 -6
- package/dist/plugins/gett/src/login.js +24 -0
- package/dist/plugins/gett/src/session.js +15 -38
- package/dist/plugins/gett/src/shared.js +41 -84
- package/dist/plugins/ghost/src/credentials.js +36 -0
- package/dist/plugins/ghost/src/index.js +18 -59
- package/dist/plugins/github/src/credentials.js +18 -0
- package/dist/plugins/github/src/index.js +55 -78
- package/dist/plugins/gitlab/src/credentials.js +24 -0
- package/dist/plugins/gitlab/src/index.js +29 -48
- package/dist/plugins/gmail/src/index.js +26 -24
- package/dist/plugins/gong/src/credentials.js +16 -0
- package/dist/plugins/gong/src/index.js +16 -32
- package/dist/plugins/googleAppsScript/src/index.js +108 -42
- package/dist/plugins/googleCalendar/src/index.js +15 -13
- package/dist/plugins/googleContacts/src/index.js +12 -9
- package/dist/plugins/googleDocs/src/index.js +2 -0
- package/dist/plugins/googleDocs/src/shared.js +2 -1
- package/dist/plugins/googleDrive/src/index.js +50 -53
- package/dist/plugins/googleImage/src/credentials.js +14 -0
- package/dist/plugins/googleImage/src/index.js +14 -25
- package/dist/plugins/googleSheets/src/index.js +26 -27
- package/dist/plugins/googleSlides/src/index.js +6 -4
- package/dist/plugins/googleTasks/src/index.js +13 -11
- package/dist/plugins/gotify/src/credentials.js +32 -0
- package/dist/plugins/gotify/src/index.js +14 -36
- package/dist/plugins/gotowebinar/src/credentials.js +13 -0
- package/dist/plugins/gotowebinar/src/index.js +52 -69
- package/dist/plugins/grafana/src/credentials.js +16 -0
- package/dist/plugins/grafana/src/index.js +34 -53
- package/dist/plugins/graphql/src/credentials.js +42 -0
- package/dist/plugins/graphql/src/index.js +21 -46
- package/dist/plugins/grist/src/credentials.js +30 -0
- package/dist/plugins/grist/src/index.js +14 -43
- package/dist/plugins/halopsa/src/credentials.js +56 -0
- package/dist/plugins/halopsa/src/index.js +20 -47
- package/dist/plugins/harvest/src/credentials.js +20 -0
- package/dist/plugins/harvest/src/index.js +24 -43
- package/dist/plugins/helpscout/src/credentials.js +13 -0
- package/dist/plugins/helpscout/src/index.js +26 -38
- package/dist/plugins/highlevel/src/credentials.js +19 -0
- package/dist/plugins/highlevel/src/index.js +34 -63
- package/dist/plugins/homeAssistant/src/credentials.js +27 -0
- package/dist/plugins/homeAssistant/src/index.js +34 -52
- package/dist/plugins/hubspot/src/credentials.js +16 -0
- package/dist/plugins/hubspot/src/index.js +29 -41
- package/dist/plugins/humanticAi/src/credentials.js +13 -0
- package/dist/plugins/humanticAi/src/index.js +15 -22
- package/dist/plugins/hunter/src/credentials.js +13 -0
- package/dist/plugins/hunter/src/index.js +18 -17
- package/dist/plugins/intercom/src/credentials.js +19 -0
- package/dist/plugins/intercom/src/index.js +25 -38
- package/dist/plugins/iterable/src/credentials.js +17 -0
- package/dist/plugins/iterable/src/index.js +26 -40
- package/dist/plugins/jenkins/src/credentials.js +16 -0
- package/dist/plugins/jenkins/src/index.js +22 -36
- package/dist/plugins/jira/src/credentials.js +16 -0
- package/dist/plugins/jira/src/index.js +35 -61
- package/dist/plugins/keap/src/credentials.js +19 -0
- package/dist/plugins/keap/src/index.js +43 -71
- package/dist/plugins/kobotoolbox/src/credentials.js +13 -0
- package/dist/plugins/kobotoolbox/src/index.js +46 -84
- package/dist/plugins/lemlist/src/credentials.js +19 -0
- package/dist/plugins/lemlist/src/index.js +35 -47
- package/dist/plugins/linear/src/attachments.js +7 -7
- package/dist/plugins/linear/src/comments.js +7 -7
- package/dist/plugins/linear/src/credentials.js +17 -0
- package/dist/plugins/linear/src/cycles.js +5 -5
- package/dist/plugins/linear/src/index.js +2 -0
- package/dist/plugins/linear/src/initiatives.js +6 -6
- package/dist/plugins/linear/src/issues.js +14 -14
- package/dist/plugins/linear/src/labels.js +6 -6
- package/dist/plugins/linear/src/organization.js +2 -2
- package/dist/plugins/linear/src/projects.js +12 -12
- package/dist/plugins/linear/src/shared.js +34 -32
- package/dist/plugins/linear/src/states.js +3 -3
- package/dist/plugins/linear/src/teams.js +4 -4
- package/dist/plugins/linear/src/users.js +3 -3
- package/dist/plugins/linear/src/views.js +5 -5
- package/dist/plugins/linear/src/webhooks.js +5 -5
- package/dist/plugins/lingvanex/src/credentials.js +13 -0
- package/dist/plugins/lingvanex/src/index.js +7 -9
- package/dist/plugins/linkedin/src/credentials.js +17 -0
- package/dist/plugins/linkedin/src/index.js +13 -17
- package/dist/plugins/lonescale/src/credentials.js +13 -0
- package/dist/plugins/lonescale/src/index.js +16 -26
- package/dist/plugins/magento/src/credentials.js +16 -0
- package/dist/plugins/magento/src/index.js +67 -84
- package/dist/plugins/mailcheck/src/credentials.js +17 -0
- package/dist/plugins/mailcheck/src/index.js +7 -9
- package/dist/plugins/mailchimp/src/credentials.js +32 -0
- package/dist/plugins/mailchimp/src/index.js +36 -44
- package/dist/plugins/mailerlite/src/credentials.js +13 -0
- package/dist/plugins/mailerlite/src/index.js +19 -32
- package/dist/plugins/mailgun/src/credentials.js +21 -0
- package/dist/plugins/mailgun/src/index.js +15 -21
- package/dist/plugins/mailjet/src/credentials.js +38 -0
- package/dist/plugins/mailjet/src/index.js +60 -115
- package/dist/plugins/mandrill/src/credentials.js +17 -0
- package/dist/plugins/mandrill/src/index.js +11 -12
- package/dist/plugins/marketstack/src/credentials.js +16 -0
- package/dist/plugins/marketstack/src/index.js +18 -28
- package/dist/plugins/matrix/src/credentials.js +19 -0
- package/dist/plugins/matrix/src/index.js +23 -52
- package/dist/plugins/mattermost/src/credentials.js +19 -0
- package/dist/plugins/mattermost/src/index.js +41 -73
- package/dist/plugins/mautic/src/credentials.js +16 -0
- package/dist/plugins/mautic/src/index.js +46 -62
- package/dist/plugins/medium/src/credentials.js +20 -0
- package/dist/plugins/medium/src/index.js +18 -23
- package/dist/plugins/messagebird/src/credentials.js +22 -0
- package/dist/plugins/messagebird/src/index.js +13 -18
- package/dist/plugins/metabase/src/credentials.js +19 -0
- package/dist/plugins/metabase/src/index.js +24 -40
- package/dist/plugins/microsoftCalendar/src/index.js +48 -12
- package/dist/plugins/microsoftFiles/src/index.js +90 -25
- package/dist/plugins/microsoftMail/src/index.js +62 -15
- package/dist/plugins/misp/src/credentials.js +16 -0
- package/dist/plugins/misp/src/index.js +60 -71
- package/dist/plugins/mocean/src/credentials.js +17 -0
- package/dist/plugins/mocean/src/index.js +11 -23
- package/dist/plugins/monday/src/credentials.js +14 -0
- package/dist/plugins/monday/src/index.js +31 -44
- package/dist/plugins/monicaCrm/src/credentials.js +19 -0
- package/dist/plugins/monicaCrm/src/index.js +25 -42
- package/dist/plugins/msg91/src/credentials.js +10 -0
- package/dist/plugins/msg91/src/index.js +15 -11
- package/dist/plugins/nasa/src/credentials.js +22 -0
- package/dist/plugins/nasa/src/index.js +24 -28
- package/dist/plugins/netlify/src/credentials.js +19 -0
- package/dist/plugins/netlify/src/index.js +27 -51
- package/dist/plugins/netscalerAdc/src/credentials.js +18 -0
- package/dist/plugins/netscalerAdc/src/index.js +16 -31
- package/dist/plugins/nextcloud/src/credentials.js +27 -0
- package/dist/plugins/nextcloud/src/index.js +55 -109
- package/dist/plugins/nocodb/src/credentials.js +16 -0
- package/dist/plugins/nocodb/src/index.js +19 -37
- package/dist/plugins/notion/src/credentials.js +21 -0
- package/dist/plugins/notion/src/index.js +25 -38
- package/dist/plugins/npm/src/credentials.js +19 -0
- package/dist/plugins/npm/src/index.js +22 -32
- package/dist/plugins/odoo/src/credentials.js +21 -0
- package/dist/plugins/odoo/src/index.js +53 -69
- package/dist/plugins/okta/src/credentials.js +23 -0
- package/dist/plugins/okta/src/index.js +30 -35
- package/dist/plugins/oneSimpleApi/src/credentials.js +16 -0
- package/dist/plugins/oneSimpleApi/src/index.js +19 -24
- package/dist/plugins/onfleet/src/credentials.js +23 -0
- package/dist/plugins/onfleet/src/index.js +42 -53
- package/dist/plugins/openai/src/credentials.js +13 -0
- package/dist/plugins/openai/src/index.js +15 -23
- package/dist/plugins/openweathermap/src/credentials.js +16 -0
- package/dist/plugins/openweathermap/src/index.js +22 -22
- package/dist/plugins/oura/src/credentials.js +19 -0
- package/dist/plugins/oura/src/index.js +13 -18
- package/dist/plugins/paddle/src/credentials.js +27 -0
- package/dist/plugins/paddle/src/index.js +20 -36
- package/dist/plugins/pagerduty/src/credentials.js +24 -0
- package/dist/plugins/pagerduty/src/index.js +30 -39
- package/dist/plugins/parallel/src/credentials.js +18 -0
- package/dist/plugins/parallel/src/index.js +16 -22
- package/dist/plugins/paypal/src/credentials.js +44 -0
- package/dist/plugins/paypal/src/index.js +14 -40
- package/dist/plugins/peekalink/src/credentials.js +16 -0
- package/dist/plugins/peekalink/src/index.js +10 -11
- package/dist/plugins/phantombuster/src/credentials.js +19 -0
- package/dist/plugins/phantombuster/src/index.js +19 -32
- package/dist/plugins/philipsHue/src/credentials.js +17 -0
- package/dist/plugins/philipsHue/src/index.js +15 -27
- package/dist/plugins/pipedrive/src/credentials.js +26 -0
- package/dist/plugins/pipedrive/src/index.js +43 -73
- package/dist/plugins/plaud/src/index.js +2 -1
- package/dist/plugins/plaud/src/shared.js +23 -19
- package/dist/plugins/plivo/src/credentials.js +20 -0
- package/dist/plugins/plivo/src/index.js +13 -19
- package/dist/plugins/posthog/src/credentials.js +18 -0
- package/dist/plugins/posthog/src/index.js +14 -20
- package/dist/plugins/profitwell/src/credentials.js +22 -0
- package/dist/plugins/profitwell/src/index.js +10 -17
- package/dist/plugins/pushbullet/src/credentials.js +19 -0
- package/dist/plugins/pushbullet/src/index.js +19 -27
- package/dist/plugins/pushcut/src/credentials.js +19 -0
- package/dist/plugins/pushcut/src/index.js +7 -8
- package/dist/plugins/pushover/src/credentials.js +14 -0
- package/dist/plugins/pushover/src/index.js +7 -12
- package/dist/plugins/quickbase/src/credentials.js +15 -0
- package/dist/plugins/quickbase/src/index.js +24 -34
- package/dist/plugins/quickbooks/src/credentials.js +22 -0
- package/dist/plugins/quickbooks/src/index.js +17 -46
- package/dist/plugins/raindrop/src/credentials.js +19 -0
- package/dist/plugins/raindrop/src/index.js +30 -32
- package/dist/plugins/recraft/src/credentials.js +13 -0
- package/dist/plugins/recraft/src/index.js +38 -27
- package/dist/plugins/reddit/src/credentials.js +26 -0
- package/dist/plugins/reddit/src/index.js +30 -34
- package/dist/plugins/replicate/src/credentials.js +23 -0
- package/dist/plugins/replicate/src/index.js +17 -27
- package/dist/plugins/rocketchat/src/credentials.js +17 -0
- package/dist/plugins/rocketchat/src/index.js +8 -19
- package/dist/plugins/rundeck/src/credentials.js +16 -0
- package/dist/plugins/rundeck/src/index.js +12 -28
- package/dist/plugins/salesforce/src/credentials.js +73 -0
- package/dist/plugins/salesforce/src/index.js +6 -0
- package/dist/plugins/salesforce/src/metadata.js +3 -16
- package/dist/plugins/salesforce/src/shared.js +25 -100
- package/dist/plugins/salesforce/src/sobjects.js +10 -9
- package/dist/plugins/salesmate/src/credentials.js +17 -0
- package/dist/plugins/salesmate/src/index.js +20 -37
- package/dist/plugins/securityScorecard/src/credentials.js +22 -0
- package/dist/plugins/securityScorecard/src/index.js +24 -37
- package/dist/plugins/segment/src/credentials.js +16 -0
- package/dist/plugins/segment/src/index.js +12 -16
- package/dist/plugins/sendgrid/src/credentials.js +13 -0
- package/dist/plugins/sendgrid/src/index.js +31 -35
- package/dist/plugins/sendy/src/credentials.js +18 -0
- package/dist/plugins/sendy/src/index.js +18 -24
- package/dist/plugins/sentry/src/credentials.js +16 -0
- package/dist/plugins/sentry/src/index.js +30 -98
- package/dist/plugins/servicenow/src/credentials.js +13 -0
- package/dist/plugins/servicenow/src/index.js +22 -41
- package/dist/plugins/shiftAtlas/src/graph.js +2 -2
- package/dist/plugins/shiftAtlas/src/index.js +2 -0
- package/dist/plugins/shiftAtlas/src/shared.js +3 -1
- package/dist/plugins/shiftBwm/src/index.js +4 -2
- package/dist/plugins/shiftBwm/src/shared.js +41 -16
- package/dist/plugins/shiftCrm/src/access.js +2 -2
- package/dist/plugins/shiftCrm/src/accounts.js +3 -3
- package/dist/plugins/shiftCrm/src/activities.js +3 -3
- package/dist/plugins/shiftCrm/src/credentials.js +6 -0
- package/dist/plugins/shiftCrm/src/index.js +2 -0
- package/dist/plugins/shiftCrm/src/opportunities.js +3 -3
- package/dist/plugins/shiftCrm/src/people.js +3 -3
- package/dist/plugins/shiftCrm/src/records.js +2 -2
- package/dist/plugins/shiftCrm/src/shared.js +2 -1
- package/dist/plugins/shiftCrm/src/tasks.js +3 -3
- package/dist/plugins/shiftObjects/src/credentials.js +2 -0
- package/dist/plugins/shiftObjects/src/index.js +2 -0
- package/dist/plugins/shiftObjects/src/objects.js +3 -2
- package/dist/plugins/shiftOcr/src/credentials.js +8 -0
- package/dist/plugins/shiftOcr/src/index.js +6 -5
- package/dist/plugins/shiftPages/src/index.js +2 -0
- package/dist/plugins/shiftPages/src/pages.js +5 -3
- package/dist/plugins/shiftPages/src/shared.js +3 -1
- package/dist/plugins/shiftTranscription/src/index.js +2 -0
- package/dist/plugins/shiftTranscription/src/shared.js +11 -1
- package/dist/plugins/shiftTranscription/src/transcription.js +4 -4
- package/dist/plugins/shiftWork/src/index.js +2 -0
- package/dist/plugins/shiftWork/src/issue-views.js +5 -5
- package/dist/plugins/shiftWork/src/issues.js +11 -7
- package/dist/plugins/shiftWork/src/projects.js +3 -3
- package/dist/plugins/shiftWork/src/shared.js +3 -1
- package/dist/plugins/shopify/src/credentials.js +16 -0
- package/dist/plugins/shopify/src/index.js +32 -59
- package/dist/plugins/signl4/src/credentials.js +17 -0
- package/dist/plugins/signl4/src/index.js +28 -29
- package/dist/plugins/slack/src/credentials.js +19 -0
- package/dist/plugins/slack/src/index.js +51 -60
- package/dist/plugins/sms77/src/credentials.js +17 -0
- package/dist/plugins/sms77/src/index.js +11 -16
- package/dist/plugins/splunk/src/credentials.js +19 -0
- package/dist/plugins/splunk/src/index.js +32 -74
- package/dist/plugins/spotify/src/credentials.js +19 -0
- package/dist/plugins/spotify/src/index.js +40 -55
- package/dist/plugins/stackby/src/credentials.js +13 -0
- package/dist/plugins/stackby/src/index.js +14 -23
- package/dist/plugins/steel/src/auth.js +27 -0
- package/dist/plugins/steel/src/browser.js +4 -3
- package/dist/plugins/steel/src/captchas.js +4 -3
- package/dist/plugins/steel/src/extensions.js +3 -2
- package/dist/plugins/steel/src/files.js +9 -10
- package/dist/plugins/steel/src/index.js +2 -0
- package/dist/plugins/steel/src/page/tools.js +3 -3
- package/dist/plugins/steel/src/profiles.js +4 -3
- package/dist/plugins/steel/src/sessions.js +13 -13
- package/dist/plugins/steel/src/shared.js +21 -51
- package/dist/plugins/storyblok/src/credentials.js +37 -0
- package/dist/plugins/storyblok/src/index.js +22 -66
- package/dist/plugins/strapi/src/credentials.js +71 -0
- package/dist/plugins/strapi/src/index.js +36 -70
- package/dist/plugins/strava/src/credentials.js +19 -0
- package/dist/plugins/strava/src/index.js +16 -33
- package/dist/plugins/stripe/src/credentials.js +19 -0
- package/dist/plugins/stripe/src/index.js +44 -58
- package/dist/plugins/supabase/src/credentials.js +30 -0
- package/dist/plugins/supabase/src/index.js +18 -40
- package/dist/plugins/syncromsp/src/credentials.js +16 -0
- package/dist/plugins/syncromsp/src/index.js +37 -70
- package/dist/plugins/tapfiliate/src/credentials.js +13 -0
- package/dist/plugins/tapfiliate/src/index.js +21 -31
- package/dist/plugins/telegram/src/credentials.js +20 -0
- package/dist/plugins/telegram/src/index.js +31 -39
- package/dist/plugins/thehive/src/credentials.js +14 -0
- package/dist/plugins/thehive/src/index.js +33 -50
- package/dist/plugins/thehiveProject/src/credentials.js +16 -0
- package/dist/plugins/thehiveProject/src/index.js +53 -122
- package/dist/plugins/todoist/src/credentials.js +26 -0
- package/dist/plugins/todoist/src/index.js +49 -79
- package/dist/plugins/together/src/credentials.js +16 -0
- package/dist/plugins/together/src/index.js +30 -32
- package/dist/plugins/travisci/src/credentials.js +24 -0
- package/dist/plugins/travisci/src/index.js +16 -30
- package/dist/plugins/trello/src/credentials.js +29 -0
- package/dist/plugins/trello/src/index.js +49 -64
- package/dist/plugins/twake/src/credentials.js +16 -0
- package/dist/plugins/twake/src/index.js +8 -10
- package/dist/plugins/twilio/src/credentials.js +23 -0
- package/dist/plugins/twilio/src/index.js +12 -26
- package/dist/plugins/twist/src/credentials.js +13 -0
- package/dist/plugins/twist/src/index.js +32 -44
- package/dist/plugins/twitter/src/credentials.js +16 -0
- package/dist/plugins/twitter/src/index.js +25 -37
- package/dist/plugins/typesafe/src/credentials.js +28 -0
- package/dist/plugins/typesafe/src/index.js +3 -1
- package/dist/plugins/typesafe/src/shared.js +23 -35
- package/dist/plugins/unleashedSoftware/src/credentials.js +21 -0
- package/dist/plugins/unleashedSoftware/src/index.js +13 -37
- package/dist/plugins/uplead/src/credentials.js +16 -0
- package/dist/plugins/uplead/src/index.js +11 -16
- package/dist/plugins/uproc/src/credentials.js +14 -0
- package/dist/plugins/uproc/src/index.js +7 -10
- package/dist/plugins/uptimerobot/src/credentials.js +14 -0
- package/dist/plugins/uptimerobot/src/index.js +28 -39
- package/dist/plugins/urlscanio/src/credentials.js +13 -0
- package/dist/plugins/urlscanio/src/index.js +13 -22
- package/dist/plugins/vercel/src/credentials.js +19 -0
- package/dist/plugins/vercel/src/deployments.js +27 -11
- package/dist/plugins/vercel/src/env.js +31 -12
- package/dist/plugins/vercel/src/index.js +2 -0
- package/dist/plugins/vercel/src/projects.js +6 -3
- package/dist/plugins/vercel/src/shared.js +32 -37
- package/dist/plugins/vero/src/credentials.js +17 -0
- package/dist/plugins/vero/src/index.js +18 -21
- package/dist/plugins/vonage/src/credentials.js +17 -0
- package/dist/plugins/vonage/src/index.js +14 -18
- package/dist/plugins/wekan/src/credentials.js +16 -0
- package/dist/plugins/wekan/src/index.js +33 -46
- package/dist/plugins/wolt/src/account.js +6 -0
- package/dist/plugins/wolt/src/catalog.js +2 -2
- package/dist/plugins/wolt/src/credentials.js +64 -0
- package/dist/plugins/wolt/src/index.js +8 -3
- package/dist/plugins/wolt/src/orders.js +2 -2
- package/dist/plugins/wolt/src/public.js +91 -0
- package/dist/plugins/wolt/src/shared.js +49 -158
- package/dist/plugins/woocommerce/src/credentials.js +16 -0
- package/dist/plugins/woocommerce/src/index.js +19 -37
- package/dist/plugins/wordpress/src/credentials.js +16 -0
- package/dist/plugins/wordpress/src/index.js +23 -42
- package/dist/plugins/xai/src/credentials.js +13 -0
- package/dist/plugins/xai/src/index.js +31 -30
- package/dist/plugins/xero/src/credentials.js +17 -0
- package/dist/plugins/xero/src/index.js +19 -36
- package/dist/plugins/yourls/src/credentials.js +17 -0
- package/dist/plugins/yourls/src/index.js +13 -23
- package/dist/plugins/zammad/src/credentials.js +15 -0
- package/dist/plugins/zammad/src/index.js +27 -47
- package/dist/plugins/zendesk/src/credentials.js +26 -0
- package/dist/plugins/zendesk/src/index.js +29 -48
- package/dist/plugins/zoho/src/credentials.js +17 -0
- package/dist/plugins/zoho/src/index.js +18 -38
- package/dist/plugins/zoom/src/credentials.js +19 -0
- package/dist/plugins/zoom/src/index.js +15 -30
- package/dist/plugins/zulip/src/credentials.js +16 -0
- package/dist/plugins/zulip/src/index.js +36 -42
- package/dist/sdk.d.ts +8 -0
- package/dist/sdk.js +3 -0
- package/package.json +1 -1
- package/dist/plugins/_shared/authedFetch.js +0 -33
- package/dist/plugins/_shared/tokenRefresh.js +0 -41
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AuthError } from "./auth/errors.js";
|
|
2
|
-
export { acquireOAuth2ClientToken, acquireOAuth2JwtToken, buildOAuth2AuthorizationUrl, exchangeOAuth2Code, refreshOAuth2Token, } from "./auth/oauth2.js";
|
|
2
|
+
export { acquireOAuth2ClientToken, acquireOAuth2JwtToken, acquireOAuth2PasswordToken, buildOAuth2AuthorizationUrl, exchangeOAuth2Code, refreshOAuth2Token, } from "./auth/oauth2.js";
|
|
3
3
|
export { decodeOAuthTokens, requestOAuth2Token } from "./auth/token.js";
|
|
4
4
|
export { addConnection, findConfigDir, getConnection, loadConfig, removeConnection, saveConfig, updateConnectionConfig, } from "./config/loader.js";
|
|
5
5
|
export { DEFAULT_CONFIG } from "./config/types.js";
|
|
@@ -8,7 +8,7 @@ export { MemoryConnectionProvider } from "./connections/memory.js";
|
|
|
8
8
|
export { ExecutionEngine } from "./core/engine.js";
|
|
9
9
|
export { buildAuthUrl, exchangeAuthCode, generatePKCE, OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_URI, oauthCallback, runOAuth, } from "./core/oauth.js";
|
|
10
10
|
export { downloadResource } from "./credentials/http.js";
|
|
11
|
-
export { CredentialRegistry, OAuthGrantSchema, OAuthTokensSchema, validateCredential, } from "./credentials/registry.js";
|
|
11
|
+
export { CredentialRegistry, OAuthGrantSchema, OAuthTokensSchema, staticSecretSchema, validateCredential, } from "./credentials/registry.js";
|
|
12
12
|
export { CredentialTransport } from "./credentials/transport.js";
|
|
13
13
|
export { createPluginAPI, isPluginFunction, resolvePluginExport, } from "./plugin/api.js";
|
|
14
14
|
export { installPlugin, listInstalled, parsePluginSource, removePlugin, } from "./plugin/installer.js";
|
package/dist/plugin/api.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CredentialDeclaration } from "../credentials/types.js";
|
|
1
2
|
import type { ActionAccess, ActionDef, ConnectionSchema, InputSchema, OAuthConfig, PluginDef } from "./types.js";
|
|
2
3
|
export interface ActionDefinition {
|
|
3
4
|
access?: ActionAccess;
|
|
@@ -16,6 +17,12 @@ export interface RunlinePluginAPI {
|
|
|
16
17
|
* with refreshable tokens.
|
|
17
18
|
*/
|
|
18
19
|
setOAuth(oauth: OAuthConfig): void;
|
|
20
|
+
/**
|
|
21
|
+
* Declare how a connection's config becomes what this plugin's requests
|
|
22
|
+
* are signed with, so a host brokering for it can sign from the plugin
|
|
23
|
+
* it loaded rather than from anything the plugin's process sends.
|
|
24
|
+
*/
|
|
25
|
+
setCredential(declaration: CredentialDeclaration): void;
|
|
19
26
|
onInit(fn: (config: Record<string, unknown>) => void): void;
|
|
20
27
|
log: {
|
|
21
28
|
info(msg: string): void;
|
package/dist/plugin/api.js
CHANGED
|
@@ -4,6 +4,7 @@ export function createPluginAPI(pluginId) {
|
|
|
4
4
|
const actions = [];
|
|
5
5
|
let connectionConfigSchema;
|
|
6
6
|
let oauth;
|
|
7
|
+
let credential;
|
|
7
8
|
const initHooks = [];
|
|
8
9
|
const api = {
|
|
9
10
|
setName(n) {
|
|
@@ -24,6 +25,9 @@ export function createPluginAPI(pluginId) {
|
|
|
24
25
|
setOAuth(cfg) {
|
|
25
26
|
oauth = { ...cfg };
|
|
26
27
|
},
|
|
28
|
+
setCredential(declaration) {
|
|
29
|
+
credential = declaration;
|
|
30
|
+
},
|
|
27
31
|
onInit(fn) {
|
|
28
32
|
initHooks.push(fn);
|
|
29
33
|
},
|
|
@@ -49,6 +53,9 @@ export function createPluginAPI(pluginId) {
|
|
|
49
53
|
if (oauth) {
|
|
50
54
|
plugin.oauth = oauth;
|
|
51
55
|
}
|
|
56
|
+
if (credential) {
|
|
57
|
+
plugin.credential = credential;
|
|
58
|
+
}
|
|
52
59
|
if (initHooks.length > 0) {
|
|
53
60
|
plugin.initHooks = initHooks;
|
|
54
61
|
}
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { TSchema } from "typebox";
|
|
2
2
|
import type { OAuth2Definition } from "../auth/types.js";
|
|
3
3
|
import type { ConnectionUpdate } from "../connections/types.js";
|
|
4
|
+
import type { CredentialBroker } from "../credentials/transport.js";
|
|
5
|
+
import type { CredentialDeclaration } from "../credentials/types.js";
|
|
4
6
|
export interface InputField {
|
|
5
7
|
type: "string" | "number" | "boolean" | "object" | "array";
|
|
6
8
|
description?: string;
|
|
@@ -60,6 +62,13 @@ export interface ActionContext {
|
|
|
60
62
|
* engine). Absent when the embedder passed none.
|
|
61
63
|
*/
|
|
62
64
|
context?: unknown;
|
|
65
|
+
/**
|
|
66
|
+
* Authenticated requests signed by the host, present when the embedder
|
|
67
|
+
* holds this connection's credentials elsewhere and the plugin declares
|
|
68
|
+
* its credential. A plugin given one sends through it and signs nothing
|
|
69
|
+
* itself: its connection config then carries public settings only.
|
|
70
|
+
*/
|
|
71
|
+
credentials?: CredentialBroker;
|
|
63
72
|
log: {
|
|
64
73
|
info(msg: string): void;
|
|
65
74
|
warn(msg: string): void;
|
|
@@ -128,6 +137,9 @@ export interface PluginDef {
|
|
|
128
137
|
connectionConfigSchema?: ConnectionSchema;
|
|
129
138
|
/** OAuth2 config for `runline auth <plugin>`. */
|
|
130
139
|
oauth?: OAuthConfig;
|
|
140
|
+
/** How a connection's config becomes what its requests are signed with;
|
|
141
|
+
* present on plugins whose requests go through the credential registry. */
|
|
142
|
+
credential?: CredentialDeclaration;
|
|
131
143
|
/** @internal */
|
|
132
144
|
initHooks?: Array<(config: Record<string, unknown>) => void>;
|
|
133
145
|
}
|
|
@@ -1,15 +1,73 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { AuthError, CredentialRegistry, CredentialTransport, } from "runline";
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Where one action call's authenticated requests go: the host's broker
|
|
5
|
+
* when it supplies one — the credentials then live with the host, and no
|
|
6
|
+
* local signer is built — else this process signs with its own
|
|
7
|
+
* connection, from the plugin's declaration.
|
|
8
|
+
*/
|
|
9
|
+
export function credentialBroker(ctx, declaration) {
|
|
10
|
+
if (ctx.credentials)
|
|
11
|
+
return ctx.credentials;
|
|
12
|
+
const { binding, transport } = localSigner(ctx, declaration);
|
|
13
|
+
return {
|
|
14
|
+
request: (input) => transport.request(binding, input),
|
|
15
|
+
probe: () => transport.probe(binding),
|
|
16
|
+
socketUrl: (input) => transport.socketUrl(binding, input),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Everything a stored token was issued under. A config whose selection
|
|
20
|
+
* hashes differently can no longer use tokens issued for this one. */
|
|
21
|
+
function authorityOf(selection) {
|
|
22
|
+
return createHash("sha256").update(JSON.stringify(selection)).digest("hex");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A static secret's structured shape, from the flat fields and fixed values
|
|
26
|
+
* the declaration names, joined in order where a part concatenates them.
|
|
27
|
+
* Absent when a required part's field is missing, so the transport refuses
|
|
28
|
+
* it as invalid_credentials before any IO; a missing optional part is left
|
|
29
|
+
* out, refusing only the targets that place it.
|
|
30
|
+
*/
|
|
31
|
+
function staticSecret(current, sources, optional) {
|
|
32
|
+
if (!sources)
|
|
33
|
+
return undefined;
|
|
34
|
+
const secret = {};
|
|
35
|
+
sources: for (const [key, source] of Object.entries(sources)) {
|
|
36
|
+
let joined = "";
|
|
37
|
+
for (const part of "concat" in source ? source.concat : [source]) {
|
|
38
|
+
const value = "value" in part ? part.value : current[part.field];
|
|
39
|
+
if (typeof value !== "string") {
|
|
40
|
+
if (optional.includes(key))
|
|
41
|
+
continue sources;
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
joined += value;
|
|
45
|
+
}
|
|
46
|
+
secret[key] = joined;
|
|
47
|
+
}
|
|
48
|
+
return secret;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* This process signing with its own connection. Flat CLI/env storage is a
|
|
52
|
+
* projection, not a second token cache or refresh engine.
|
|
53
|
+
*/
|
|
54
|
+
function localSigner(ctx, declaration) {
|
|
55
|
+
const selection = declaration(ctx.connection.config);
|
|
56
|
+
const { type: definition, method } = selection;
|
|
57
|
+
if (!Object.hasOwn(definition.methods, method))
|
|
58
|
+
throw new AuthError("invalid_definition");
|
|
59
|
+
const auth = definition.methods[method].authentication;
|
|
5
60
|
const identity = { name: ctx.connection.name, plugin: ctx.connection.plugin };
|
|
6
|
-
const
|
|
7
|
-
.update(JSON.stringify([definition.id, method, authority(config)]))
|
|
8
|
-
.digest("hex");
|
|
9
|
-
const expected = fingerprint(ctx.connection.config);
|
|
61
|
+
const expected = authorityOf(selection);
|
|
10
62
|
const project = (current) => {
|
|
11
|
-
if (
|
|
63
|
+
if (authorityOf(declaration(current)) !== expected)
|
|
12
64
|
throw new AuthError("binding_changed");
|
|
65
|
+
if (auth.kind === "none")
|
|
66
|
+
return {};
|
|
67
|
+
if (auth.kind === "static") {
|
|
68
|
+
const secret = staticSecret(current, selection.localSecret, auth.optionalParts ?? []);
|
|
69
|
+
return secret ? { [auth.field]: secret } : {};
|
|
70
|
+
}
|
|
13
71
|
const compatible = current.authTokenBinding === undefined ||
|
|
14
72
|
current.authTokenBinding === expected;
|
|
15
73
|
const tokens = {
|
|
@@ -34,7 +92,7 @@ export function credentialRuntime(ctx, definition, method, authority) {
|
|
|
34
92
|
const revision = typeof current.authTokenRevision === "string" && compatible
|
|
35
93
|
? current.authTokenRevision
|
|
36
94
|
: createHash("sha256").update(JSON.stringify(tokens)).digest("hex");
|
|
37
|
-
return {
|
|
95
|
+
return { [auth.field]: { tokens, revision } };
|
|
38
96
|
};
|
|
39
97
|
const snapshot = () => ({
|
|
40
98
|
...identity,
|
|
@@ -44,21 +102,25 @@ export function credentialRuntime(ctx, definition, method, authority) {
|
|
|
44
102
|
type: definition.id,
|
|
45
103
|
method,
|
|
46
104
|
identity,
|
|
47
|
-
application:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
105
|
+
application: selection.application,
|
|
106
|
+
...(selection.jwtIdentity ? { jwtIdentity: selection.jwtIdentity } : {}),
|
|
107
|
+
...(selection.resourceOwner
|
|
108
|
+
? { resourceOwner: selection.resourceOwner }
|
|
109
|
+
: {}),
|
|
51
110
|
connection: {
|
|
52
111
|
async read() {
|
|
53
112
|
return snapshot();
|
|
54
113
|
},
|
|
55
114
|
async update(change) {
|
|
115
|
+
// Only an OAuth grant is ever renewed and written back.
|
|
116
|
+
if (auth.kind !== "oauth2")
|
|
117
|
+
throw new AuthError("invalid_definition");
|
|
56
118
|
await ctx.updateConnection(async (current) => {
|
|
57
119
|
const projected = project(current);
|
|
58
120
|
const patch = typeof change === "function" ? await change(projected) : change;
|
|
59
121
|
if (!patch)
|
|
60
122
|
return;
|
|
61
|
-
const grant = patch.
|
|
123
|
+
const grant = patch[auth.field];
|
|
62
124
|
if (!grant?.tokens.accessToken)
|
|
63
125
|
throw new AuthError("invalid_credentials");
|
|
64
126
|
return {
|
|
@@ -77,10 +139,12 @@ export function credentialRuntime(ctx, definition, method, authority) {
|
|
|
77
139
|
};
|
|
78
140
|
const registry = new CredentialRegistry();
|
|
79
141
|
registry.register(definition);
|
|
80
|
-
//
|
|
81
|
-
//
|
|
142
|
+
// The widest defaults the transport allows, so an undeclared slow call
|
|
143
|
+
// (image generation, exports) is bounded rather than cut short; targets
|
|
144
|
+
// that declare their own deadline or ceiling get it up to the host caps.
|
|
82
145
|
const transport = new CredentialTransport(registry, {
|
|
83
146
|
fetch: globalThis.fetch,
|
|
147
|
+
timeoutMs: 120_000,
|
|
84
148
|
maxRequestBytes: 64 * 1024 * 1024,
|
|
85
149
|
maxResponseBytes: 64 * 1024 * 1024,
|
|
86
150
|
});
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { AuthError, OAuthGrantSchema, staticSecretSchema, } from "runline";
|
|
2
|
+
import * as t from "typebox";
|
|
3
|
+
import { credentialBroker } from "./credentialAdapter.js";
|
|
4
|
+
/**
|
|
5
|
+
* The plugin side of the credential broker, shared by every plugin: one
|
|
6
|
+
* declaration factory for static keys, one stored grant shape for OAuth
|
|
7
|
+
* methods, one way to turn public config into an HTTPS target, one
|
|
8
|
+
* request path.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The stored shape of an OAuth method: one optional revisioned grant in the
|
|
12
|
+
* `grant` field, absent until the first issuance.
|
|
13
|
+
*/
|
|
14
|
+
export const grantSchema = t.Object({ grant: t.Optional(OAuthGrantSchema) }, { additionalProperties: false });
|
|
15
|
+
/** The parts and placements a shorthand, or the general form, declares. */
|
|
16
|
+
function placementsOf(auth) {
|
|
17
|
+
if (auth.kind === "static") {
|
|
18
|
+
const { kind: _, ...declared } = auth;
|
|
19
|
+
return declared;
|
|
20
|
+
}
|
|
21
|
+
if (auth.kind === "basic")
|
|
22
|
+
return {
|
|
23
|
+
parts: ["username", "password"],
|
|
24
|
+
placements: [{ in: "basic", username: "username", password: "password" }],
|
|
25
|
+
};
|
|
26
|
+
const placement = auth.kind === "bearer"
|
|
27
|
+
? {
|
|
28
|
+
in: "header",
|
|
29
|
+
part: "secret",
|
|
30
|
+
name: "Authorization",
|
|
31
|
+
prefix: "Bearer ",
|
|
32
|
+
}
|
|
33
|
+
: auth.kind === "queryKey"
|
|
34
|
+
? { in: "query", part: "secret", name: auth.param }
|
|
35
|
+
: {
|
|
36
|
+
in: "header",
|
|
37
|
+
part: "secret",
|
|
38
|
+
name: auth.header,
|
|
39
|
+
...(auth.prefix === undefined ? {} : { prefix: auth.prefix }),
|
|
40
|
+
};
|
|
41
|
+
return { parts: ["secret"], placements: [placement] };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A static-key plugin's declaration. The secret lives in one structured
|
|
45
|
+
* `credential` field — `{ secret }`, `{ username, password }` for basic, or
|
|
46
|
+
* the general form's named parts — and the method is named for the auth
|
|
47
|
+
* kind, so every static declaration has the same shape. A host stores the
|
|
48
|
+
* structured field; the CLI's flat fields are named by `local`.
|
|
49
|
+
*/
|
|
50
|
+
export function staticCredential(spec) {
|
|
51
|
+
const field = "credential";
|
|
52
|
+
const { parts, optionalParts, placements } = placementsOf(spec.auth);
|
|
53
|
+
if (Object.keys(spec.local).sort().join() !== [...parts].sort().join())
|
|
54
|
+
throw new AuthError("invalid_definition");
|
|
55
|
+
const localSecret = Object.fromEntries(Object.entries(spec.local).map(([key, source]) => [
|
|
56
|
+
key,
|
|
57
|
+
typeof source === "string" ? { field: source } : source,
|
|
58
|
+
]));
|
|
59
|
+
const fields = Object.values(localSecret).flatMap((source) => ("concat" in source ? source.concat : [source]).flatMap((part) => "field" in part ? [part.field] : []));
|
|
60
|
+
return (config) => {
|
|
61
|
+
const targets = typeof spec.targets === "function" ? spec.targets(config) : spec.targets;
|
|
62
|
+
const signed = !spec.optional ||
|
|
63
|
+
config.authenticated === true ||
|
|
64
|
+
fields.every((name) => typeof config[name] === "string" && config[name]);
|
|
65
|
+
return {
|
|
66
|
+
type: {
|
|
67
|
+
id: spec.id,
|
|
68
|
+
methods: {
|
|
69
|
+
[spec.auth.kind]: {
|
|
70
|
+
schema: t.Object({ [field]: staticSecretSchema(parts, optionalParts) }, { additionalProperties: false }),
|
|
71
|
+
authentication: {
|
|
72
|
+
kind: "static",
|
|
73
|
+
field,
|
|
74
|
+
parts,
|
|
75
|
+
...(optionalParts ? { optionalParts } : {}),
|
|
76
|
+
placements,
|
|
77
|
+
},
|
|
78
|
+
targets,
|
|
79
|
+
...(spec.probe ? { probe: spec.probe } : {}),
|
|
80
|
+
},
|
|
81
|
+
...(spec.optional
|
|
82
|
+
? {
|
|
83
|
+
none: {
|
|
84
|
+
schema: t.Object({}, { additionalProperties: false }),
|
|
85
|
+
authentication: { kind: "none" },
|
|
86
|
+
targets: spec.optional === true ? targets : spec.optional.targets,
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
: {}),
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
...(signed
|
|
93
|
+
? { method: spec.auth.kind, localSecret }
|
|
94
|
+
: { method: "none" }),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* An HTTPS base URL from public config, with `path` appended beneath it.
|
|
100
|
+
* Anything else — plain HTTP, embedded credentials, a query or fragment —
|
|
101
|
+
* is invalid_credentials: the connection cannot be signed as configured.
|
|
102
|
+
*/
|
|
103
|
+
export function httpsBase(value, path) {
|
|
104
|
+
try {
|
|
105
|
+
if (typeof value !== "string")
|
|
106
|
+
throw new Error();
|
|
107
|
+
const url = new URL(value);
|
|
108
|
+
if (url.protocol !== "https:" ||
|
|
109
|
+
url.username ||
|
|
110
|
+
url.password ||
|
|
111
|
+
url.search ||
|
|
112
|
+
url.hash ||
|
|
113
|
+
value.includes("?") ||
|
|
114
|
+
value.includes("#"))
|
|
115
|
+
throw new Error();
|
|
116
|
+
const base = url.pathname.endsWith("/") ? url.pathname : `${url.pathname}/`;
|
|
117
|
+
return `${url.origin}${base}${path}`;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
throw new AuthError("invalid_credentials");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** One DNS label from public config, for `https://{label}.provider.com/` hosts. */
|
|
124
|
+
export function hostLabel(value) {
|
|
125
|
+
if (typeof value !== "string" ||
|
|
126
|
+
!/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(value))
|
|
127
|
+
throw new AuthError("invalid_credentials");
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* One of a config field's documented values — a region, an environment,
|
|
132
|
+
* a hosting mode — or `fallback` when the field is absent. Anything else
|
|
133
|
+
* is invalid_credentials, never mapped to a default: a mistyped value
|
|
134
|
+
* would otherwise send the credential to another host.
|
|
135
|
+
*/
|
|
136
|
+
export function configChoice(value, choices, fallback) {
|
|
137
|
+
if (value === undefined || value === null)
|
|
138
|
+
return fallback;
|
|
139
|
+
if (typeof value !== "string" ||
|
|
140
|
+
!choices.includes(value))
|
|
141
|
+
throw new AuthError("invalid_credentials");
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A boolean config field, as a boolean or the string a CLI or environment
|
|
146
|
+
* variable gives (`"true"`, `"false"`); false when absent. Anything else
|
|
147
|
+
* is invalid_credentials, as for `configChoice`: a mistyped sandbox or
|
|
148
|
+
* SSL flag must not read as false and reach the live host.
|
|
149
|
+
*/
|
|
150
|
+
export function configFlag(value) {
|
|
151
|
+
if (typeof value === "boolean")
|
|
152
|
+
return value;
|
|
153
|
+
return configChoice(value, ["true", "false"], "false") === "true";
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* An ID or name as exactly one path segment, the one encoder every plugin
|
|
157
|
+
* uses. A value that is not one segment is refused rather than encoded: an
|
|
158
|
+
* empty value would address the parent collection (`items/`), a dot segment
|
|
159
|
+
* a sibling, and a separator more than one segment.
|
|
160
|
+
*/
|
|
161
|
+
export function pathSegment(value) {
|
|
162
|
+
const raw = value === undefined || value === null ? "" : String(value);
|
|
163
|
+
if (!raw || raw === "." || raw === ".." || /[/\\]/.test(raw))
|
|
164
|
+
throw new AuthError("request_not_allowed");
|
|
165
|
+
return encodeURIComponent(raw);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* A slash-separated name the API addresses as a sub-path — a model's
|
|
169
|
+
* `owner/name`, a file path, a nested job — each segment by `pathSegment`,
|
|
170
|
+
* its slashes kept.
|
|
171
|
+
*/
|
|
172
|
+
export function pathSegments(value) {
|
|
173
|
+
return String(value ?? "")
|
|
174
|
+
.split("/")
|
|
175
|
+
.map(pathSegment)
|
|
176
|
+
.join("/");
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* A slashed name as exactly one segment, its slashes encoded
|
|
180
|
+
* (`@scope/pkg` → `%40scope%2Fpkg`), for a target that declares
|
|
181
|
+
* `encodedSlashes`. An empty or dot piece, or a backslash, is refused.
|
|
182
|
+
*/
|
|
183
|
+
export function slashEncodedSegment(value) {
|
|
184
|
+
return pathSegments(value).replaceAll("/", "%2F");
|
|
185
|
+
}
|
|
186
|
+
/** Parameters as `a=1&b=2`: arrays repeat the key; null and undefined are skipped. */
|
|
187
|
+
function encodeParams(params) {
|
|
188
|
+
const encoded = new URLSearchParams();
|
|
189
|
+
for (const [key, value] of Object.entries(params)) {
|
|
190
|
+
if (value === undefined || value === null)
|
|
191
|
+
continue;
|
|
192
|
+
for (const entry of Array.isArray(value) ? value : [value])
|
|
193
|
+
encoded.append(key, String(entry));
|
|
194
|
+
}
|
|
195
|
+
return encoded.toString();
|
|
196
|
+
}
|
|
197
|
+
function withQuery(path, query) {
|
|
198
|
+
if (!query)
|
|
199
|
+
return path;
|
|
200
|
+
const encoded = encodeParams(query);
|
|
201
|
+
if (!encoded)
|
|
202
|
+
return path;
|
|
203
|
+
return `${path}${path.includes("?") ? "&" : "?"}${encoded}`;
|
|
204
|
+
}
|
|
205
|
+
/** The one authenticated request path: the host's broker, else the local signer. */
|
|
206
|
+
export function credentialRequest(ctx, declaration, call) {
|
|
207
|
+
const body = call.json !== undefined
|
|
208
|
+
? { type: "application/json", body: JSON.stringify(call.json) }
|
|
209
|
+
: call.form !== undefined
|
|
210
|
+
? {
|
|
211
|
+
type: "application/x-www-form-urlencoded",
|
|
212
|
+
body: encodeParams(call.form),
|
|
213
|
+
}
|
|
214
|
+
: undefined;
|
|
215
|
+
const payload = body?.body ?? call.body;
|
|
216
|
+
return credentialBroker(ctx, declaration).request({
|
|
217
|
+
target: call.target,
|
|
218
|
+
path: withQuery(call.path, call.query),
|
|
219
|
+
method: call.method ?? "GET",
|
|
220
|
+
headers: {
|
|
221
|
+
Accept: "application/json",
|
|
222
|
+
...(body ? { "Content-Type": body.type } : {}),
|
|
223
|
+
...call.headers,
|
|
224
|
+
},
|
|
225
|
+
...(payload !== undefined ? { body: payload } : {}),
|
|
226
|
+
...(call.destination !== undefined
|
|
227
|
+
? { destination: call.destination }
|
|
228
|
+
: {}),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* A step that writes a grant into the connection — an owner login run
|
|
233
|
+
* against the provider — happens only where the grant lives: this process,
|
|
234
|
+
* signing with its own connection. Under a host that keeps the grant, setup
|
|
235
|
+
* is the host's, and the step refuses before any request.
|
|
236
|
+
*/
|
|
237
|
+
export function refuseUnderHost(ctx) {
|
|
238
|
+
if (ctx.credentials)
|
|
239
|
+
throw new AuthError("unsupported_operation");
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* A socket target's URL for this connection, from the broker: signed by
|
|
243
|
+
* the local signer, or a relay the host controls. A broker that serves no
|
|
244
|
+
* sockets refuses as unsupported_operation.
|
|
245
|
+
*/
|
|
246
|
+
export async function credentialSocketUrl(ctx, declaration, call) {
|
|
247
|
+
const broker = credentialBroker(ctx, declaration);
|
|
248
|
+
if (!broker.socketUrl)
|
|
249
|
+
throw new AuthError("unsupported_operation");
|
|
250
|
+
return broker.socketUrl({
|
|
251
|
+
target: call.target,
|
|
252
|
+
path: withQuery(call.path, call.query),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* A provider error identifier worth handing back — an error code, a field
|
|
257
|
+
* path — as a plain name. Anything else is not a name and is dropped, so
|
|
258
|
+
* the code and field slots of a failure never carry free text.
|
|
259
|
+
*/
|
|
260
|
+
export function errorIdentifier(value) {
|
|
261
|
+
return typeof value === "string" && /^[\w.$:-]{1,100}$/.test(value)
|
|
262
|
+
? value
|
|
263
|
+
: undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* How a failed request reads: its HTTP status when the status is the
|
|
267
|
+
* failure, and the identifiers a provider returns for correcting the call
|
|
268
|
+
* — its error `code` and the offending `param`. A failed response's body
|
|
269
|
+
* is never read into it: that is where a provider may echo the credential.
|
|
270
|
+
*/
|
|
271
|
+
export function failureMessage(plugin, status, detail = {}) {
|
|
272
|
+
const identifiers = [detail.code, detail.param && `param: ${detail.param}`]
|
|
273
|
+
.filter(Boolean)
|
|
274
|
+
.join(", ");
|
|
275
|
+
const inner = [status === undefined ? "" : `HTTP ${status}`, identifiers]
|
|
276
|
+
.filter(Boolean)
|
|
277
|
+
.join(" ");
|
|
278
|
+
return `${plugin}: request failed${inner ? ` (${inner})` : ""}`;
|
|
279
|
+
}
|
|
280
|
+
/** A code or field path as a plain identifier, numbers included. */
|
|
281
|
+
function identifierOf(value) {
|
|
282
|
+
return errorIdentifier(typeof value === "number" ? String(value) : value);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* A successful response whose answer reports failure — Slack's `ok: false`,
|
|
286
|
+
* an OCS status, a GraphQL `errors` entry — by the provider's code, the
|
|
287
|
+
* field at fault and its message. The answer is 2xx data the plugin
|
|
288
|
+
* already holds, so the message stays for the caller to act on, reduced
|
|
289
|
+
* to one line of at most 300 characters.
|
|
290
|
+
*/
|
|
291
|
+
export function answerFailed(plugin, detail) {
|
|
292
|
+
const head = failureMessage(plugin, undefined, {
|
|
293
|
+
code: identifierOf(detail.code),
|
|
294
|
+
param: identifierOf(detail.param),
|
|
295
|
+
});
|
|
296
|
+
const text = typeof detail.message === "string"
|
|
297
|
+
? detail.message.replace(/[\u0000-\u001f\u007f\s]+/g, " ").trim()
|
|
298
|
+
: "";
|
|
299
|
+
const line = text.length > 300 ? `${text.slice(0, 300)}…` : text;
|
|
300
|
+
return new Error(line ? `${head}: ${line}` : head);
|
|
301
|
+
}
|
|
302
|
+
/** A GraphQL answer's `errors`, read by `answerFailed` from the first entry. */
|
|
303
|
+
export function graphqlFailed(plugin, errors) {
|
|
304
|
+
const first = (Array.isArray(errors) ? errors[0] : undefined);
|
|
305
|
+
return answerFailed(plugin, {
|
|
306
|
+
code: first?.extensions?.code,
|
|
307
|
+
param: Array.isArray(first?.path) ? first.path.join(".") : undefined,
|
|
308
|
+
message: first?.message,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/** A failed request, reported by status alone. */
|
|
312
|
+
export function requestFailed(plugin, status) {
|
|
313
|
+
return new Error(failureMessage(plugin, status));
|
|
314
|
+
}
|
|
315
|
+
/** A request that must succeed, for callers that read the Response itself (headers, text, bytes). */
|
|
316
|
+
export async function credentialOk(ctx, declaration, plugin, call) {
|
|
317
|
+
const response = await credentialRequest(ctx, declaration, call);
|
|
318
|
+
if (!response.ok)
|
|
319
|
+
throw requestFailed(plugin, response.status);
|
|
320
|
+
return response;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* A successful response's JSON. `T` is the caller's statement of the
|
|
324
|
+
* answer's shape, unchecked, as for any parsed JSON; without one it is
|
|
325
|
+
* `unknown`. An empty answer is `EmptyAnswer`, so a caller whose endpoint
|
|
326
|
+
* can answer empty includes it in `T`. Every JSON request path reads its
|
|
327
|
+
* answer here, so they cannot disagree about empty or malformed bodies.
|
|
328
|
+
*/
|
|
329
|
+
export async function jsonAnswer(response) {
|
|
330
|
+
const empty = { success: true };
|
|
331
|
+
if (response.status === 204)
|
|
332
|
+
return empty;
|
|
333
|
+
const text = await response.text();
|
|
334
|
+
if (!text)
|
|
335
|
+
return empty;
|
|
336
|
+
try {
|
|
337
|
+
return JSON.parse(text);
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
throw new AuthError("invalid_response");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* A successful response's JSON when its Content-Type says JSON; any other
|
|
345
|
+
* body — a text "OK", nothing at all — is an acknowledgement,
|
|
346
|
+
* `EmptyAnswer`. For APIs whose writes answer without JSON.
|
|
347
|
+
*/
|
|
348
|
+
export async function jsonOrAcknowledged(response) {
|
|
349
|
+
return (response.headers.get("content-type") ?? "").includes("application/json")
|
|
350
|
+
? jsonAnswer(response)
|
|
351
|
+
: { success: true };
|
|
352
|
+
}
|
|
353
|
+
/** A JSON request that must succeed; its answer is read by `jsonAnswer`. */
|
|
354
|
+
export async function credentialJson(ctx, declaration, plugin, call) {
|
|
355
|
+
return jsonAnswer(await credentialOk(ctx, declaration, plugin, call));
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* A next-page URL the API returned, as a path beneath the declared target
|
|
359
|
+
* it will be signed for. Anything outside that target's exact origin and
|
|
360
|
+
* path prefix is refused rather than followed with the credential attached.
|
|
361
|
+
*/
|
|
362
|
+
export function pathWithin(ctx, declaration, target, value) {
|
|
363
|
+
const { type, method } = declaration(ctx.connection.config);
|
|
364
|
+
const targets = type.methods[method]?.targets ?? {};
|
|
365
|
+
if (!Object.hasOwn(targets, target))
|
|
366
|
+
throw new AuthError("request_not_allowed");
|
|
367
|
+
try {
|
|
368
|
+
const base = new URL(targets[target].baseUrl);
|
|
369
|
+
const url = new URL(value);
|
|
370
|
+
if (url.origin !== base.origin ||
|
|
371
|
+
url.username ||
|
|
372
|
+
url.password ||
|
|
373
|
+
url.hash ||
|
|
374
|
+
!url.pathname.startsWith(base.pathname))
|
|
375
|
+
throw new Error();
|
|
376
|
+
return `${url.pathname.slice(base.pathname.length)}${url.search}`;
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
throw new AuthError("request_not_allowed");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/** FormData as the buffered bytes the transport accepts, with its boundary. */
|
|
383
|
+
export async function multipartBody(form) {
|
|
384
|
+
const response = new Response(form);
|
|
385
|
+
const contentType = response.headers.get("content-type");
|
|
386
|
+
if (!contentType)
|
|
387
|
+
throw new AuthError("request_not_allowed");
|
|
388
|
+
return { body: new Uint8Array(await response.arrayBuffer()), contentType };
|
|
389
|
+
}
|