diff --git a/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tests.tsx b/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tests.tsx
index 3a4ce73d9e..83f0190c14 100644
--- a/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tests.tsx
+++ b/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tests.tsx
@@ -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(
+
+ );
+
+ 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(
+
+ );
+
+ 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(
+
+ );
+
+ 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();
+ });
});
diff --git a/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tsx b/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tsx
index 1fcc3c00fa..da2b905323 100644
--- a/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tsx
+++ b/frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsErrorCell/OSSettingsErrorCell.tsx
@@ -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 (?.*) certificate authority is invalid/
+ );
+ if (matchTokenErr?.groups) {
+ return (
+ <>
+ Couldn't get certificate from DigiCert. The API token{" "}
+ configured in {matchTokenErr.groups.ca} certificate authority is
+ invalid. Please go to{" "}
+
+ Settings {">"} Integrations {">"} Certificates
+
+ , correct it and resend.
+ >
+ );
+ }
+
+ const matchProfileIdErr = detail.match(
+ /get certificate from (?:DigiCert|Digicert|digicert).*profile_id.*configured in (?.*) certificate authority does(?:n.t| not) exist/
+ );
+ if (matchProfileIdErr?.groups) {
+ return (
+ <>
+ Couldn't get certificate from DigiCert. The Profile GUID{" "}
+ configured in {matchProfileIdErr.groups.ca} certificate authority
+ doesn't exist. Please go to{" "}
+
+ Settings {">"} Integrations {">"} Certificates
+
+ , correct it and resend.
+ >
+ );
+ }
+
+ const matchFleetVarErr = detail.match(
+ /populate (?.*) because (?.*) certificate authority does(?:n.t| not) exist/
+ );
+ if (matchFleetVarErr?.groups) {
+ return (
+ <>
+ Fleet couldn't populate {matchFleetVarErr.groups.field} because{" "}
+ {matchFleetVarErr.groups.ca} certificate authority doesn't
+ exist. Please go to{" "}
+
+ Settings {">"} Integrations {">"} Certificates
+
+ , 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.
+
+ Fleet couldn't populate
+
+ $FLEET_VAR_HOST_END_USER_EMAIL_IDP.
+
+
+ >
+ );
+ }
+ 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.
-
- Fleet couldn't populate
-
- $FLEET_VAR_HOST_END_USER_EMAIL_IDP.
-
-
- >
- );
+ // 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 {