Skip to content

Commit 95af7cf

Browse files
authored
fix(editor): Design fixes for managed OAuth credentials (#26064)
1 parent 05d15a0 commit 95af7cf

File tree

5 files changed

+132
-2
lines changed

5 files changed

+132
-2
lines changed

packages/frontend/editor-ui/src/features/credentials/components/CredentialEdit/CredentialConfig.test.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,118 @@ describe('CredentialConfig', () => {
326326
expect(screen.getByTestId('dynamic-credentials-toggle')).toBeInTheDocument();
327327
});
328328
});
329+
330+
describe('OAuth Redirect URL', () => {
331+
const writePermissions = {
332+
create: true,
333+
update: true,
334+
read: true,
335+
delete: true,
336+
share: true,
337+
list: true,
338+
move: true,
339+
};
340+
341+
it('should show redirect URL for OAuth credentials without managed OAuth', () => {
342+
renderComponent({
343+
pinia: createTestingPinia({
344+
initialState: {
345+
[STORES.SETTINGS]: {
346+
settings: { enterprise: { sharing: false, externalSecrets: false } },
347+
},
348+
[STORES.ROOT]: {
349+
oauthCallbackUrls: { oauth2: 'https://example.com/callback' },
350+
},
351+
},
352+
}),
353+
props: {
354+
isManaged: false,
355+
mode: 'new',
356+
credentialType: mockCredentialType,
357+
credentialProperties: [],
358+
credentialData: {} as ICredentialDataDecryptedObject,
359+
isOAuthType: true,
360+
managedOauthAvailable: false,
361+
useCustomOauth: false,
362+
credentialPermissions: writePermissions,
363+
},
364+
});
365+
366+
expect(screen.getByTestId('copy-input')).toBeInTheDocument();
367+
});
368+
369+
it('should show redirect URL when managed OAuth is available but user chose custom', () => {
370+
renderComponent({
371+
pinia: createTestingPinia({
372+
initialState: {
373+
[STORES.SETTINGS]: {
374+
settings: { enterprise: { sharing: false, externalSecrets: false } },
375+
},
376+
[STORES.ROOT]: {
377+
oauthCallbackUrls: { oauth2: 'https://example.com/callback' },
378+
},
379+
},
380+
}),
381+
props: {
382+
isManaged: false,
383+
mode: 'new',
384+
credentialType: mockCredentialType,
385+
credentialProperties: [],
386+
credentialData: {} as ICredentialDataDecryptedObject,
387+
isOAuthType: true,
388+
managedOauthAvailable: true,
389+
useCustomOauth: true,
390+
credentialPermissions: writePermissions,
391+
},
392+
});
393+
394+
expect(screen.getByTestId('copy-input')).toBeInTheDocument();
395+
});
396+
397+
it('should not show redirect URL when using managed OAuth', () => {
398+
renderComponent({
399+
pinia: createTestingPinia({
400+
initialState: {
401+
[STORES.SETTINGS]: {
402+
settings: { enterprise: { sharing: false, externalSecrets: false } },
403+
},
404+
[STORES.ROOT]: {
405+
oauthCallbackUrls: { oauth2: 'https://example.com/callback' },
406+
},
407+
},
408+
}),
409+
props: {
410+
isManaged: false,
411+
mode: 'new',
412+
credentialType: mockCredentialType,
413+
credentialProperties: [],
414+
credentialData: {} as ICredentialDataDecryptedObject,
415+
isOAuthType: true,
416+
managedOauthAvailable: true,
417+
useCustomOauth: false,
418+
credentialPermissions: writePermissions,
419+
},
420+
});
421+
422+
expect(screen.queryByTestId('copy-input')).not.toBeInTheDocument();
423+
});
424+
425+
it('should not show redirect URL for non-OAuth credentials', () => {
426+
renderComponent({
427+
props: {
428+
isManaged: false,
429+
mode: 'new',
430+
credentialType: mockCredentialType,
431+
credentialProperties: [],
432+
credentialData: {} as ICredentialDataDecryptedObject,
433+
isOAuthType: false,
434+
managedOauthAvailable: false,
435+
useCustomOauth: false,
436+
credentialPermissions: writePermissions,
437+
},
438+
});
439+
440+
expect(screen.queryByTestId('copy-input')).not.toBeInTheDocument();
441+
});
442+
});
329443
});

packages/frontend/editor-ui/src/features/credentials/components/CredentialEdit/CredentialConfig.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ const canWrite = computed(() => {
214214
return canCreate.value || canEdit.value;
215215
});
216216
217+
const isManagedOAuth = computed(
218+
() => props.isOAuthType && props.managedOauthAvailable && !props.useCustomOauth,
219+
);
220+
217221
function onDataChange(event: IUpdateInformation): void {
218222
emit('update', event);
219223
}
@@ -273,7 +277,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
273277
/>
274278

275279
<N8nCallout
276-
v-if="documentationUrl && credentialProperties.length"
280+
v-if="documentationUrl && credentialProperties.length && !isManagedOAuth"
277281
:class="$style.docsCallout"
278282
theme="custom"
279283
iconless
@@ -402,7 +406,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
402406
</div>
403407

404408
<CopyInput
405-
v-if="isOAuthType && useCustomOauth"
409+
v-if="isOAuthType && !isManagedOAuth"
406410
:label="i18n.baseText('credentialEdit.credentialConfig.oAuthRedirectUrl')"
407411
:value="oAuthCallbackUrl"
408412
:copy-button-text="i18n.baseText('credentialEdit.credentialConfig.clickToCopy')"

packages/frontend/editor-ui/src/features/credentials/components/CredentialEdit/CredentialEdit.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,7 @@ const { width } = useElementSize(credNameRef);
13531353
/>
13541354
<SaveButton
13551355
v-if="showSaveButton"
1356+
:class="$style.saveButton"
13561357
:disabled="!hasUnsavedChanges && !isTesting && !!credentialId"
13571358
:is-saving="isSaving || isTesting"
13581359
:saved="false"
@@ -1378,6 +1379,7 @@ const { width } = useElementSize(credNameRef);
13781379
/>
13791380
<SaveButton
13801381
v-if="showSaveButton"
1382+
:class="$style.saveButton"
13811383
:disabled="!hasUnsavedChanges && !isTesting && !!credentialId"
13821384
:is-saving="isSaving || isTesting"
13831385
:saved="false"
@@ -1486,4 +1488,8 @@ const { width } = useElementSize(credNameRef);
14861488
align-items: center;
14871489
margin-right: var(--spacing--xs);
14881490
}
1491+
1492+
.saveButton {
1493+
margin-left: 1px;
1494+
}
14891495
</style>

packages/nodes-base/credentials/GoogleBusinessProfileOAuth2Api.credentials.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export class GoogleBusinessProfileOAuth2Api implements ICredentialType {
2424
name: 'notice',
2525
type: 'notice',
2626
default: '',
27+
displayOptions: {
28+
hideOnCloud: true,
29+
},
2730
},
2831
];
2932
}

packages/nodes-base/credentials/GoogleDriveOAuth2Api.credentials.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export class GoogleDriveOAuth2Api implements ICredentialType {
2828
name: 'notice',
2929
type: 'notice',
3030
default: '',
31+
displayOptions: {
32+
hideOnCloud: true,
33+
},
3134
},
3235
];
3336
}

0 commit comments

Comments
 (0)