Skip to content

Add support for OAuth inside array items with credentials (e.g., source-shopify-native) #1892

@JustinASmith

Description

@JustinASmith

OAuth renderer does not support credentials inside array items

Problem

The UI OAuth renderer assumes credentials live at a fixed top-level path in the endpoint config. When a connector schema places credentials inside array items (e.g. a stores array where each item has its own credentials object), the OAuth flow breaks because:

  1. The Mustache templates in the connector's OAuth2Spec reference fields like {{{ config.store }}}, but the actual value lives at config.stores[N].store -- the backend cannot resolve it.
  2. The authURL and accessToken API calls send the raw endpoint config, which has no top-level store field for the template to bind to.

The OAuth renderer already handles being rendered inside an array (it detects array paths via isInsideArray and writes tokens back to the correct index via handleChange), but the config sent to the backend for template rendering is not adjusted.

Impact

Any connector whose schema uses an array of items with per-item OAuth credentials will hit this. The immediate case is the Shopify source connector, which is migrating to a multi-store array model. Once the OAuth app is approved and the connector ships the multi-store update, users will not be able to authenticate individual stores through the UI.

Proposal

Introduce a Virtual Config Flattening step in useOauthHandler that intercepts the config before it is sent to the backend. When the OAuth renderer detects it is inside an array item (via the JSONForms path prop), it:

  1. Extracts the array field name and index from the path (e.g. stores.2.credentials -> array stores, index 2)
  2. Reads the current array item from the endpoint config
  3. Promotes scalar fields from that item to the top level of a shallow config copy
  4. Sends this virtual config to authURL() and accessToken() instead of the raw config

Non-array OAuth flows are unaffected -- when the path has no array index the original config passes through unchanged.

Scope

  • ~50 lines of new code across 3 modified files + 1 new utility module
  • 2 new test files (28 tests)
  • Zero changes to backend, protocol, CDK, or connector code
  • No breaking changes to existing OAuth connectors

Key files

  • ui/src/forms/shared.ts -- new getArrayContext() utility
  • ui/src/forms/renderers/OAuth/buildVirtualConfig.ts -- new module, pure function
  • ui/src/forms/renderers/OAuth/useOauthHandler.ts -- accepts credentialsPath, uses virtual config
  • ui/src/forms/renderers/OAuth/index.tsx -- passes path to handler

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    connectorsRelated to connectorsenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions