From f619655a61b312928dccc6838539c3a9dec7a532 Mon Sep 17 00:00:00 2001 From: Konstantin Sykulev Date: Mon, 1 Jun 2026 10:01:47 -0500 Subject: [PATCH] Certificate template duplicate name error (#46414) **Related issue:** Resolves #44821 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] QA'd all new/changed functionality manually ## Summary by CodeRabbit * **Bug Fixes** * Fixed inline validation to show duplicate certificate name errors even when the conflicting certificate is on a different page. * Improved server-side error handling during certificate creation to better detect name conflicts and present clearer, focused feedback on the Name field. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46414?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --- changes/44821-certificate-template-err | 1 + .../AddCertificateModal/AddCertificateModal.tsx | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 changes/44821-certificate-template-err diff --git a/changes/44821-certificate-template-err b/changes/44821-certificate-template-err new file mode 100644 index 0000000000..d85a2ae52d --- /dev/null +++ b/changes/44821-certificate-template-err @@ -0,0 +1 @@ +- Fixed inline error for duplicate certificate name not showing when the conflicting certificate is on a different page. diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsx b/frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsx index 01b4ab796b..f8afcfca05 100644 --- a/frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsx +++ b/frontend/pages/ManageControlsPage/OSSettings/cards/Certificates/components/AddCertificateModal/AddCertificateModal.tsx @@ -58,9 +58,9 @@ const AddCertModal = ({ subjectAlternativeName: "", }); // Server-side validation errors keyed by form field; cleared when the user - // edits the corresponding input. Today only SAN can come back with a - // field-targeted 422; other fields fall through to the generic flash. + // edits the corresponding input. const [serverErrors, setServerErrors] = useState<{ + name?: string; subjectAlternativeName?: string; }>({}); @@ -102,6 +102,9 @@ const AddCertModal = ({ const onInputChange = (update: { name: string; value: string }) => { const updatedFormData = { ...formData, [update.name]: update.value }; setFormData(updatedFormData); + if (update.name === "name" && serverErrors.name) { + setServerErrors((prev) => ({ ...prev, name: undefined })); + } if ( update.name === "subjectAlternativeName" && serverErrors.subjectAlternativeName @@ -145,8 +148,15 @@ const AddCertModal = ({ const sanReason = getErrorReason(e, { nameEquals: "subject_alternative_name", }); + const nameConflict = getErrorReason(e, { + reasonIncludes: "already exists", + }); if (sanReason) { setServerErrors({ subjectAlternativeName: sanReason }); + } else if (nameConflict) { + setServerErrors({ + name: "Name is already used by another certificate.", + }); } else { renderFlash("error", "Couldn't add certificate. Please try again."); } @@ -170,7 +180,7 @@ const AddCertModal = ({ label="Name" value={formData.name} onChange={onInputChange} - error={formValidation.name?.message} + error={serverErrors.name ?? formValidation.name?.message} helpText="Letters, numbers, spaces, dashes, and underscores only. Name can be used as certificate alias to reference in configuration profiles." parseTarget placeholder="VPN certificate"