From 689da21ccee1dc0b4770a97c558099fd40494ef2 Mon Sep 17 00:00:00 2001 From: "Elias W. BA" Date: Mon, 9 Mar 2026 11:46:11 +0000 Subject: [PATCH 1/3] fix: allow credentials on common adaptor Remove the hardcoded check that prevented credential selection for @openfn/language-common jobs. Users need raw JSON credentials on common adaptor steps for workflow reusability (e.g., facility-specific config). When creating a new credential from a common adaptor job, default to the "raw" (Raw JSON) schema since common has no dedicated schema file. --- .../components/ConfigureAdaptorModal.tsx | 42 +++++++------------ .../components/ConfigureAdaptorModal.test.tsx | 27 ++++++------ 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/assets/js/collaborative-editor/components/ConfigureAdaptorModal.tsx b/assets/js/collaborative-editor/components/ConfigureAdaptorModal.tsx index 9b3597e98c..935da823ba 100644 --- a/assets/js/collaborative-editor/components/ConfigureAdaptorModal.tsx +++ b/assets/js/collaborative-editor/components/ConfigureAdaptorModal.tsx @@ -277,13 +277,6 @@ export function ConfigureAdaptorModal({ onCredentialChange, ]); - // Check if the adaptor requires credentials - const adaptorNeedsCredentials = useMemo(() => { - const adaptorName = extractAdaptorName(currentAdaptor); - // Common adaptor doesn't require credentials - return adaptorName !== 'common'; - }, [currentAdaptor]); - // Filter credentials into sections const credentialSections = useMemo(() => { const adaptorName = extractAdaptorName(currentAdaptor); @@ -442,7 +435,10 @@ export function ConfigureAdaptorModal({ const handleCreateCredential = () => { const adaptorName = extractAdaptorName(currentAdaptor); if (adaptorName) { - onOpenCredentialModal(adaptorName); + // Adaptors like "common" have no credential schema file, so default + // to "raw" (Raw JSON) which is the most flexible credential type. + const schema = adaptorName === 'common' ? 'raw' : adaptorName; + onOpenCredentialModal(schema); } }; @@ -590,27 +586,19 @@ export function ConfigureAdaptorModal({ /> - {adaptorNeedsCredentials && ( - - )} + - {!adaptorNeedsCredentials ? ( -
-

- This adaptor does not require credentials. -

-
- ) : credentialSections.schemaMatched.length === 0 && - credentialSections.universal.length === 0 && - credentialSections.keychain.length === 0 ? ( + {credentialSections.schemaMatched.length === 0 && + credentialSections.universal.length === 0 && + credentialSections.keychain.length === 0 ? (

No credentials found in this project diff --git a/assets/test/collaborative-editor/components/ConfigureAdaptorModal.test.tsx b/assets/test/collaborative-editor/components/ConfigureAdaptorModal.test.tsx index 78115c4e6d..68ffb84a47 100644 --- a/assets/test/collaborative-editor/components/ConfigureAdaptorModal.test.tsx +++ b/assets/test/collaborative-editor/components/ConfigureAdaptorModal.test.tsx @@ -742,7 +742,7 @@ describe('ConfigureAdaptorModal', () => { expect(radioButtons.length).toBe(3); }); - it("shows informative message for adaptors that don't need credentials", () => { + it('shows universal and keychain credentials for common adaptor', () => { renderWithProviders( { /> ); - // Should show message that adaptor doesn't need credentials + // Should NOT show message that adaptor doesn't need credentials expect( - screen.getByText('This adaptor does not require credentials.') - ).toBeInTheDocument(); - - // Should NOT show credential list or New Credential button - expect(screen.queryByText('HTTP API Key')).not.toBeInTheDocument(); - expect(screen.queryByText('Keychain Salesforce')).not.toBeInTheDocument(); - expect( - screen.queryByText('Salesforce Production') + screen.queryByText('This adaptor does not require credentials.') ).not.toBeInTheDocument(); - // New Credential button should be hidden + // Should show universal credentials (http, raw, oauth) and keychain + expect(screen.getByText('HTTP API Key')).toBeInTheDocument(); + expect(screen.getByText('Keychain Salesforce')).toBeInTheDocument(); + + // Should NOT show schema-specific credentials (no schema matches "common") expect( - screen.queryByRole('button', { name: /new credential/i }) + screen.queryByText('Salesforce Production') ).not.toBeInTheDocument(); - // Should NOT show "Back to matching credentials" link (no matching credentials to go back to) + // New Credential button should be available expect( - screen.queryByText(/back to matching credentials/i) - ).not.toBeInTheDocument(); + screen.getByRole('button', { name: /new credential/i }) + ).toBeInTheDocument(); }); it('allows manual toggle between matching and other credentials', async () => { From 1a6208758e58c737bb03882dfccb1ea222fd8bf0 Mon Sep 17 00:00:00 2001 From: "Elias W. BA" Date: Mon, 9 Mar 2026 12:14:39 +0000 Subject: [PATCH 2/3] chore: add changelog entry for common adaptor credentials fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2fb1ddb5..00ca7024b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to ### Fixed +- Allow credentials (raw JSON, HTTP, OAuth) on common adaptor jobs + ## [2.15.16] - 2026-03-09 ## [2.15.16-pre.3] - 2026-03-09 From b6a5d2f5ed6ac5c301dd0f5c24aab7be437dd29a Mon Sep 17 00:00:00 2001 From: "Elias W. BA" Date: Mon, 9 Mar 2026 12:18:59 +0000 Subject: [PATCH 3/3] chore: add PR link to changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cff2bffa8b..28f4e8eeb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to ### Fixed - Allow credentials (raw JSON, HTTP, OAuth) on common adaptor jobs + [#4513](https://github.com/OpenFn/lightning/pull/4513) - Migrate form error display from `phx-feedback-for` to `used_input?/1` so validation errors only appear on fields the user has interacted with [#4472](https://github.com/OpenFn/lightning/pull/4472)