mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Add UI tooltips for errors related to certificates feature in host MDM profiles (#27252)
This commit is contained in:
parent
84892741dd
commit
dd99760ee6
2 changed files with 163 additions and 22 deletions
|
|
@ -100,4 +100,64 @@ describe("OSSettingsErrorCell", () => {
|
|||
expect(screen.getByText(/Learn more/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Learn more/).tagName.toLowerCase()).toBe("a");
|
||||
});
|
||||
|
||||
it("renders a formatted tooltip when the error message matches custom scep error patern", () => {
|
||||
render(
|
||||
<OSSettingsErrorCell
|
||||
canResendProfiles
|
||||
hostId={1}
|
||||
profile={createMockHostMdmProfile({
|
||||
status: "failed",
|
||||
detail: `Fleet couldn’t populate $FLEET_VAR_CUSTOM_SCEP_URL_SCEP_WIFI because SCEP_WIFI certificate authority doesn’t exist.`,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText("Settings > Integrations > Certificates")
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/add it and resend the configuration profile/)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders a formatted tooltip when the error message matches digicert guid patern", () => {
|
||||
render(
|
||||
<OSSettingsErrorCell
|
||||
canResendProfiles
|
||||
hostId={1}
|
||||
profile={createMockHostMdmProfile({
|
||||
status: "failed",
|
||||
detail: `Couldn’t get certificate from DigiCert. The "profile_id" configured in DIGICERT_WIFI certificate authority doesn’t exist.`,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText("Settings > Integrations > Certificates")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/correct it and resend/)).toBeInTheDocument();
|
||||
expect(screen.getByText("DIGICERT_WIFI")).toBeInTheDocument();
|
||||
expect(screen.getByText("Profile GUID")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders a formatted tooltip when the error message matches digicert token patern", () => {
|
||||
render(
|
||||
<OSSettingsErrorCell
|
||||
canResendProfiles
|
||||
hostId={1}
|
||||
profile={createMockHostMdmProfile({
|
||||
status: "failed",
|
||||
detail: `Couldn’t get certificate from DigiCert. The API token configured in DIGICERT_TEST certificate authority is invalid.`,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText("Settings > Integrations > Certificates")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/correct it and resend/)).toBeInTheDocument();
|
||||
expect(screen.getByText("DIGICERT_TEST")).toBeInTheDocument();
|
||||
expect(screen.getByText("API token")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
|
|||
import hostAPI from "services/entities/hosts";
|
||||
import { NotificationContext } from "context/notification";
|
||||
|
||||
import { IHostMdmProfile } from "interfaces/mdm";
|
||||
|
||||
import TooltipTruncatedTextCell from "components/TableContainer/DataTable/TooltipTruncatedTextCell";
|
||||
import Button from "components/buttons/Button";
|
||||
import Icon from "components/Icon";
|
||||
|
|
@ -42,12 +44,99 @@ const RefetchButton = ({ isFetching, onClick }: IRefetchButtonProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* formatDetailCertificateError generates the formatted detail for certain errors related to
|
||||
* certificate profiles. It return a JSX element with the formatted message or null if
|
||||
* the detail does not match any of the expected patterns.
|
||||
*/
|
||||
const formatDetailCertificateError = (detail: IHostMdmProfile["detail"]) => {
|
||||
const matchTokenErr = detail.match(
|
||||
/get certificate from (?:DigiCert|Digicert|digicert).*token configured in (?<ca>.*) certificate authority is invalid/
|
||||
);
|
||||
if (matchTokenErr?.groups) {
|
||||
return (
|
||||
<>
|
||||
Couldn't get certificate from DigiCert. The <b>API token</b>{" "}
|
||||
configured in <b>{matchTokenErr.groups.ca}</b> certificate authority is
|
||||
invalid. Please go to{" "}
|
||||
<b>
|
||||
Settings {">"} Integrations {">"} Certificates
|
||||
</b>
|
||||
, correct it and resend.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const matchProfileIdErr = detail.match(
|
||||
/get certificate from (?:DigiCert|Digicert|digicert).*profile_id.*configured in (?<ca>.*) certificate authority does(?:n.t| not) exist/
|
||||
);
|
||||
if (matchProfileIdErr?.groups) {
|
||||
return (
|
||||
<>
|
||||
Couldn't get certificate from DigiCert. The <b>Profile GUID</b>{" "}
|
||||
configured in <b>{matchProfileIdErr.groups.ca}</b> certificate authority
|
||||
doesn't exist. Please go to{" "}
|
||||
<b>
|
||||
Settings {">"} Integrations {">"} Certificates
|
||||
</b>
|
||||
, correct it and resend.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const matchFleetVarErr = detail.match(
|
||||
/populate (?<field>.*) because (?<ca>.*) certificate authority does(?:n.t| not) exist/
|
||||
);
|
||||
if (matchFleetVarErr?.groups) {
|
||||
return (
|
||||
<>
|
||||
Fleet couldn't populate {matchFleetVarErr.groups.field} because{" "}
|
||||
<b>{matchFleetVarErr.groups.ca}</b> certificate authority doesn't
|
||||
exist. Please go to{" "}
|
||||
<b>
|
||||
Settings {">"} Integrations {">"} Certificates
|
||||
</b>
|
||||
, add it and resend the configuration profile.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* formatDetailIdpEmailError generates the formatted detail for certain errors related to
|
||||
* host IdP email profiles. It returns a JSX element with the formatted message or null if
|
||||
* the detail does not match any of the expected patterns.
|
||||
*/
|
||||
const formatDetailIdpEmailError = (detail: IHostMdmProfile["detail"]) => {
|
||||
if (detail.includes("There is no IdP email for this host.")) {
|
||||
return (
|
||||
<>
|
||||
There is no IdP email for this host.
|
||||
<br />
|
||||
Fleet couldn't populate
|
||||
<br />
|
||||
$FLEET_VAR_HOST_END_USER_EMAIL_IDP.
|
||||
<br />
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url="https://fleetdm.com/learn-more-about/idp-email"
|
||||
newTab
|
||||
variant="tooltip-link"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* generates the formatted tooltip for the error column.
|
||||
* the expected format of the error string is:
|
||||
* "key1: value1, key2: value2, key3: value3"
|
||||
*/
|
||||
const generateFormattedTooltip = (detail: string) => {
|
||||
const formatDetailWindowsProfile = (detail: string) => {
|
||||
const keyValuePairs = detail.split(/, */);
|
||||
const formattedElements: JSX.Element[] = [];
|
||||
|
||||
|
|
@ -90,31 +179,23 @@ const generateErrorTooltip = (
|
|||
) => {
|
||||
if (profile.status !== "failed") return null;
|
||||
|
||||
// Special case for creating UI link
|
||||
if (profile.detail.includes("There is no IdP email for this host.")) {
|
||||
return (
|
||||
<>
|
||||
There is no IdP email for this host.
|
||||
<br />
|
||||
Fleet couldn't populate
|
||||
<br />
|
||||
$FLEET_VAR_HOST_END_USER_EMAIL_IDP.
|
||||
<br />
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url="https://fleetdm.com/learn-more-about/idp-email"
|
||||
newTab
|
||||
variant="tooltip-link"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
// Special case to handle IdP email errors
|
||||
const idpEmailError = formatDetailIdpEmailError(profile.detail);
|
||||
if (idpEmailError) {
|
||||
return idpEmailError;
|
||||
}
|
||||
|
||||
if (profile.platform !== "windows") {
|
||||
return cellValue;
|
||||
// Special case to handle certificate profile errors
|
||||
const certificateError = formatDetailCertificateError(profile.detail);
|
||||
if (certificateError) {
|
||||
return certificateError;
|
||||
}
|
||||
|
||||
return generateFormattedTooltip(profile.detail);
|
||||
if (profile.platform === "windows") {
|
||||
return formatDetailWindowsProfile(profile.detail);
|
||||
}
|
||||
|
||||
return cellValue;
|
||||
};
|
||||
|
||||
interface IOSSettingsErrorCellProps {
|
||||
|
|
|
|||
Loading…
Reference in a new issue