diff --git a/ee/server/service/certificate_authorities.go b/ee/server/service/certificate_authorities.go
index ff731f5759..db31010970 100644
--- a/ee/server/service/certificate_authorities.go
+++ b/ee/server/service/certificate_authorities.go
@@ -866,6 +866,10 @@ func (svc *Service) UpdateCertificateAuthority(ctx context.Context, id uint, p f
var caActivityName string
if p.DigiCertCAUpdatePayload != nil {
+ if p.DigiCertCAUpdatePayload.IsEmpty() {
+ return &fleet.BadRequestError{Message: fmt.Sprintf("%sDigiCert CA update payload is empty", errPrefix)}
+ }
+
if err := p.DigiCertCAUpdatePayload.ValidateRelatedFields(errPrefix, *oldCA.Name); err != nil {
return err
}
@@ -890,6 +894,10 @@ func (svc *Service) UpdateCertificateAuthority(ctx context.Context, id uint, p f
activity = fleet.ActivityEditedDigiCert{Name: caActivityName}
}
if p.HydrantCAUpdatePayload != nil {
+ if p.HydrantCAUpdatePayload.IsEmpty() {
+ return &fleet.BadRequestError{Message: fmt.Sprintf("%sHydrant CA update payload is empty", errPrefix)}
+ }
+
if err := p.HydrantCAUpdatePayload.ValidateRelatedFields(errPrefix, *oldCA.Name); err != nil {
return err
}
@@ -910,6 +918,10 @@ func (svc *Service) UpdateCertificateAuthority(ctx context.Context, id uint, p f
activity = fleet.ActivityEditedHydrant{Name: caActivityName}
}
if p.NDESSCEPProxyCAUpdatePayload != nil {
+ if p.NDESSCEPProxyCAUpdatePayload.IsEmpty() {
+ return &fleet.BadRequestError{Message: fmt.Sprintf("%sNDES SCEP Proxy CA update payload is empty", errPrefix)}
+ }
+
if err := p.NDESSCEPProxyCAUpdatePayload.ValidateRelatedFields(errPrefix, *oldCA.Name); err != nil {
return err
}
@@ -930,6 +942,10 @@ func (svc *Service) UpdateCertificateAuthority(ctx context.Context, id uint, p f
activity = fleet.ActivityEditedNDESSCEPProxy{}
}
if p.CustomSCEPProxyCAUpdatePayload != nil {
+ if p.CustomSCEPProxyCAUpdatePayload.IsEmpty() {
+ return &fleet.BadRequestError{Message: fmt.Sprintf("%sCustom SCEP Proxy CA update payload is empty", errPrefix)}
+ }
+
if err := p.CustomSCEPProxyCAUpdatePayload.ValidateRelatedFields(errPrefix, *oldCA.Name); err != nil {
return err
}
diff --git a/ee/server/service/certificate_authorities_test.go b/ee/server/service/certificate_authorities_test.go
index 7b6f78355a..2b43e6f7c7 100644
--- a/ee/server/service/certificate_authorities_test.go
+++ b/ee/server/service/certificate_authorities_test.go
@@ -1009,6 +1009,30 @@ func TestUpdatingCertificateAuthorities(t *testing.T) {
require.EqualError(t, err, "Couldn't edit certificate authority. Certificate authority with ID 999 does not exist.")
})
+ t.Run("Errors on empty inner update payload", func(t *testing.T) {
+ svc, ctx := baseSetupForCATests()
+ payloadMap := map[uint]fleet.CertificateAuthorityUpdatePayload{
+ digicertID: {
+ DigiCertCAUpdatePayload: &fleet.DigiCertCAUpdatePayload{},
+ },
+ hydrantID: {
+ HydrantCAUpdatePayload: &fleet.HydrantCAUpdatePayload{},
+ },
+ scepID: {
+ CustomSCEPProxyCAUpdatePayload: &fleet.CustomSCEPProxyCAUpdatePayload{},
+ },
+ ndesID: {
+ NDESSCEPProxyCAUpdatePayload: &fleet.NDESSCEPProxyCAUpdatePayload{},
+ },
+ }
+
+ for id, payload := range payloadMap {
+
+ err := svc.UpdateCertificateAuthority(ctx, id, payload)
+ require.Contains(t, err.Error(), "update payload is empty")
+ }
+ })
+
t.Run("Errors on wrong existing CA type", func(t *testing.T) {
svc, ctx := baseSetupForCATests()
diff --git a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tests.tsx b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tests.tsx
index 78d24f3d96..b9befc7214 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tests.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tests.tsx
@@ -40,7 +40,7 @@ describe("CustomSCEPForm", () => {
/>
);
- // data is valid, submit should be enabled
+ // data is valid, so submit should be enabled
expect(screen.getByRole("button", { name: "Submit" })).toBeEnabled();
// name input is invalidated, submit should be disabled
@@ -62,4 +62,36 @@ describe("CustomSCEPForm", () => {
expect(screen.getByRole("button", { name: "Submit" })).toBeDisabled();
});
+
+ it("submit button is disabled if isDirty is false", () => {
+ render(
+
+ );
+
+ expect(screen.getByRole("button", { name: "Submit" })).toBeDisabled();
+ });
+
+ it("submit button is enabled if isDirty", () => {
+ render(
+
+ );
+
+ expect(screen.getByRole("button", { name: "Submit" })).toBeEnabled();
+ });
});
diff --git a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsx b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsx
index 337d2aa96a..d936aa656e 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/CustomSCEPForm/CustomSCEPForm.tsx
@@ -27,6 +27,7 @@ interface ICustomSCEPFormProps {
submitBtnText: string;
isSubmitting: boolean;
isEditing?: boolean;
+ isDirty?: boolean;
onChange: (update: { name: string; value: string }) => void;
onSubmit: () => void;
onCancel: () => void;
@@ -38,6 +39,7 @@ const CustomSCEPForm = ({
submitBtnText,
isSubmitting,
isEditing = false,
+ isDirty = true,
onChange,
onSubmit,
onCancel,
@@ -113,7 +115,7 @@ const CustomSCEPForm = ({
diff --git a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tests.tsx b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tests.tsx
index 6e3c0d8450..b4c5b68e9a 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tests.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tests.tsx
@@ -44,7 +44,7 @@ describe("DigicertForm", () => {
/>
);
- // data is valid, submit should be enabled
+ // data is valid, so submit should be enabled
expect(screen.getByRole("button", { name: "Submit" })).toBeEnabled();
// name input is invalidated, submit should be disabled
@@ -66,4 +66,36 @@ describe("DigicertForm", () => {
expect(screen.getByRole("button", { name: "Submit" })).toBeDisabled();
});
+
+ it("submit button is disabled if isDirty is false", () => {
+ render(
+
+ );
+
+ expect(screen.getByRole("button", { name: "Submit" })).toBeDisabled();
+ });
+
+ it("submit button is enabled if isDirty", () => {
+ render(
+
+ );
+
+ expect(screen.getByRole("button", { name: "Submit" })).toBeEnabled();
+ });
});
diff --git a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsx b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsx
index 58af394941..18521b8d9e 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/DigicertForm.tsx
@@ -31,6 +31,7 @@ interface IDigicertFormProps {
submitBtnText: string;
isSubmitting: boolean;
isEditing?: boolean;
+ isDirty?: boolean;
onChange: (update: { name: string; value: string }) => void;
onSubmit: () => void;
onCancel: () => void;
@@ -42,6 +43,7 @@ const DigicertForm = ({
submitBtnText,
isSubmitting,
isEditing = false,
+ isDirty = true,
onChange,
onSubmit,
onCancel,
@@ -166,7 +168,7 @@ const DigicertForm = ({
>