diff --git a/backend/oauth_connect.json b/backend/oauth_connect.json index 01becd80f3..9c79919cac 100644 --- a/backend/oauth_connect.json +++ b/backend/oauth_connect.json @@ -210,5 +210,22 @@ "instance_url": "https://{instance}.service-now.com" } } + }, + "netsuite": { + "connect_config_template": { + "display_name": "NetSuite", + "label": "NetSuite Account ID", + "placeholder": " as in your NetSuite domain, e.g. 1234567 or 1234567-sb1", + "help_url": "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_157769826287.html", + "auth_url": "https://{instance}.app.netsuite.com/app/login/oauth2/authorize.nl", + "token_url": "https://{instance}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token", + "req_body_auth": false, + "strip_suffix": ".app.netsuite.com", + "scopes": ["rest_webservices"], + "extra_params_key": "account_id", + "resource_mapping": { + "account_id": "{instance}" + } + } } } diff --git a/backend/windmill-oauth/src/lib.rs b/backend/windmill-oauth/src/lib.rs index 252f7ace28..16c854dbf5 100644 --- a/backend/windmill-oauth/src/lib.rs +++ b/backend/windmill-oauth/src/lib.rs @@ -130,6 +130,10 @@ pub struct ConnectConfigTemplate { pub token_url: String, #[serde(skip_serializing_if = "Option::is_none")] pub req_body_auth: Option, + /// Scopes copied into the built `connect_config` (e.g. NetSuite's + /// `rest_webservices`). Templated providers default to no scopes. + #[serde(skip_serializing_if = "Option::is_none")] + pub scopes: Option>, /// Key under `connect_config.extra_params` where the instance name is /// stored (defaults to `instance`). Snowflake uses `account_identifier` for /// backward compatibility with previously-saved configs. diff --git a/frontend/src/lib/components/InstanceSettings.svelte b/frontend/src/lib/components/InstanceSettings.svelte index 9581357e84..5238fd78e2 100644 --- a/frontend/src/lib/components/InstanceSettings.svelte +++ b/frontend/src/lib/components/InstanceSettings.svelte @@ -308,7 +308,7 @@ instanceInputs[name] = v if (oauths[name].connect_config?.extra_params?.[key] === v) continue oauths[name].connect_config = { - scopes: [], + scopes: tmpl.scopes ?? [], auth_url: tmpl.auth_url.replaceAll('{instance}', v), token_url: tmpl.token_url.replaceAll('{instance}', v), req_body_auth: tmpl.req_body_auth ?? false, diff --git a/frontend/src/lib/components/icons/NetsuiteIcon.svelte b/frontend/src/lib/components/icons/NetsuiteIcon.svelte new file mode 100644 index 0000000000..768bbbc99e --- /dev/null +++ b/frontend/src/lib/components/icons/NetsuiteIcon.svelte @@ -0,0 +1,19 @@ + + + + + + diff --git a/frontend/src/lib/components/icons/index.ts b/frontend/src/lib/components/icons/index.ts index 56d77c810c..1870f1f6a9 100644 --- a/frontend/src/lib/components/icons/index.ts +++ b/frontend/src/lib/components/icons/index.ts @@ -34,6 +34,7 @@ import TelegramIcon from './TelegramIcon.svelte' import FunkwhaleIcon from './FunkwhaleIcon.svelte' import GdocsIcon from './GdocsIcon.svelte' import NextcloudIcon from './NextcloudIcon.svelte' +import NetsuiteIcon from './NetsuiteIcon.svelte' import FaunadbIcon from './FaunadbIcon.svelte' import ClickhouseIcon from './ClickhouseIcon.svelte' import OpenaiIcon from './OpenaiIcon.svelte' @@ -248,6 +249,7 @@ export const APP_TO_ICON_COMPONENT = { hubspot: HubspotIcon, datadog: DatadogIcon, databricks: DatabricksIcon, + netsuite: NetsuiteIcon, adobe_acrobat_sign: AdobeAcrobatSignIcon, stripe: StripeIcon, telegram: TelegramIcon,