fix(core): Fix OIDC configuration update path (#19065)

This commit is contained in:
Andreas Fitzek
2025-09-02 14:09:46 +02:00
committed by GitHub
parent 6d405a6d66
commit 1ced801358
5 changed files with 201 additions and 16 deletions

View File

@@ -3000,6 +3000,7 @@
"settings.sso.settings.save.activate.cancel": "Cancel",
"settings.sso.settings.save.activate.test": "Test settings",
"settings.sso.settings.save.error": "Error saving SAML SSO configuration",
"settings.sso.settings.save.error_oidc": "Error saving OIDC SSO configuration",
"settings.sso.settings.footer.hint": "Don't forget to activate SAML SSO once you've saved the settings.",
"settings.sso.actionBox.title": "Available on the Enterprise plan",
"settings.sso.actionBox.description": "Use Single Sign On to consolidate authentication into a single platform to improve security and agility.",

View File

@@ -331,6 +331,11 @@ describe('SettingsSso View', () => {
ssoStore.isOidcLoginEnabled = true;
ssoStore.isSamlLoginEnabled = false;
ssoStore.getOidcConfig.mockResolvedValue({
...oidcConfig,
discoveryEndpoint: '',
});
const { getByTestId, getByRole } = renderView();
// Set authProtocol component ref to OIDC
@@ -382,6 +387,66 @@ describe('SettingsSso View', () => {
}),
);
});
it('shows error message to user when OIDC config save fails', async () => {
const error = new Error('Save failed');
ssoStore.saveOidcConfig.mockRejectedValue(error);
ssoStore.isEnterpriseOidcEnabled = true;
ssoStore.isEnterpriseSamlEnabled = false;
ssoStore.isOidcLoginEnabled = true;
ssoStore.isSamlLoginEnabled = false;
ssoStore.getOidcConfig.mockResolvedValue({
...oidcConfig,
discoveryEndpoint: '',
});
const { getByTestId, getByRole } = renderView();
showError.mockClear();
// Set authProtocol component ref to OIDC
const protocolSelect = getByRole('combobox');
expect(protocolSelect).toBeInTheDocument();
await userEvent.click(protocolSelect);
const dropdown = await waitFor(() => getByRole('listbox'));
expect(dropdown).toBeInTheDocument();
const items = dropdown.querySelectorAll('.el-select-dropdown__item');
const oidcItem = Array.from(items).find((item) => item.textContent?.includes('OIDC'));
expect(oidcItem).toBeDefined();
await userEvent.click(oidcItem!);
const saveButton = await waitFor(() => getByTestId('sso-oidc-save'));
expect(saveButton).toBeVisible();
const oidcDiscoveryUrlInput = getByTestId('oidc-discovery-endpoint');
expect(oidcDiscoveryUrlInput).toBeVisible();
await userEvent.type(oidcDiscoveryUrlInput, oidcConfig.discoveryEndpoint);
const clientIdInput = getByTestId('oidc-client-id');
expect(clientIdInput).toBeVisible();
await userEvent.type(clientIdInput, 'test-client-id');
const clientSecretInput = getByTestId('oidc-client-secret');
expect(clientSecretInput).toBeVisible();
await userEvent.type(clientSecretInput, 'test-client-secret');
expect(saveButton).not.toBeDisabled();
await userEvent.click(saveButton);
expect(ssoStore.saveOidcConfig).toHaveBeenCalledWith(
expect.objectContaining({
discoveryEndpoint: oidcConfig.discoveryEndpoint,
clientId: 'test-client-id',
clientSecret: 'test-client-secret',
loginEnabled: true,
}),
);
expect(telemetryTrack).not.toBeCalled();
expect(showError).toHaveBeenCalledWith(error, 'Error saving OIDC SSO configuration');
});
});
describe('Protocol Selection Persistence', () => {

View File

@@ -284,18 +284,25 @@ async function onOidcSettingsSave() {
if (confirmAction !== MODAL_CONFIRM) return;
}
const newConfig = await ssoStore.saveOidcConfig({
clientId: clientId.value,
clientSecret: clientSecret.value,
discoveryEndpoint: discoveryEndpoint.value,
loginEnabled: ssoStore.isOidcLoginEnabled,
});
try {
const newConfig = await ssoStore.saveOidcConfig({
clientId: clientId.value,
clientSecret: clientSecret.value,
discoveryEndpoint: discoveryEndpoint.value,
loginEnabled: ssoStore.isOidcLoginEnabled,
});
// Update store with saved protocol selection
ssoStore.selectedAuthProtocol = authProtocol.value;
// Update store with saved protocol selection
ssoStore.selectedAuthProtocol = authProtocol.value;
clientSecret.value = newConfig.clientSecret;
trackUpdateSettings();
clientSecret.value = newConfig.clientSecret;
trackUpdateSettings();
} catch (error) {
toast.showError(error, i18n.baseText('settings.sso.settings.save.error_oidc'));
return;
} finally {
await getOidcConfig();
}
}
</script>