add UI for certificate authority list (#26955)
For #26605 This is the UI for the certificate authority list that shows the added CAs. This includes: **new CA section and list on integration page**  **empty CA list state**  **gitops mode on add CA card and CA list**   - [ ] Added/updated automated tests - [x] Manual QA for all new/changed functionality
This commit is contained in:
@@ -30,16 +30,16 @@ const GitOpsModeTooltipWrapper = ({
|
||||
|
||||
const tipContent = (
|
||||
// at this point repoURL will always be defined
|
||||
<>
|
||||
<div className={`${baseClass}__tooltip-content`}>
|
||||
{repoURL && (
|
||||
<>
|
||||
<span>
|
||||
Manage in{" "}
|
||||
<CustomLink newTab text="YAML" variant="tooltip-link" url={repoURL} />
|
||||
<br />
|
||||
</>
|
||||
</span>
|
||||
)}
|
||||
(GitOps mode enabled)
|
||||
</>
|
||||
<span>(GitOps mode enabled)</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
.gitops-mode-tooltip-wrapper {
|
||||
&__tooltip-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.component__tooltip-wrapper {
|
||||
&__tip-text {
|
||||
cursor: default;
|
||||
|
||||
@@ -17,6 +17,7 @@ export type ISupportedGraphicNames = Extract<
|
||||
| "file-pkg"
|
||||
| "file-p7m"
|
||||
| "file-pem"
|
||||
| "file-certificate"
|
||||
>;
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -13,6 +13,7 @@ import FilePkg from "./FilePkg";
|
||||
import FileP7m from "./FileP7m";
|
||||
import FilePem from "./FilePem";
|
||||
import FileVpp from "./FileVpp";
|
||||
import FileCertificate from "./FileCertificate";
|
||||
import AppStore from "./AppStore";
|
||||
import EmptyHosts from "./EmptyHosts";
|
||||
import EmptyTeams from "./EmptyTeams";
|
||||
@@ -49,6 +50,7 @@ export const GRAPHIC_MAP = {
|
||||
"file-p7m": FileP7m,
|
||||
"file-pem": FilePem,
|
||||
"file-vpp": FileVpp,
|
||||
"file-certificate": FileCertificate,
|
||||
"app-store": AppStore, // Used in non-editable file uploader for vpp apps edit modal
|
||||
// Other graphics
|
||||
"collecting-results": CollectingResults,
|
||||
|
||||
@@ -17,13 +17,30 @@ export interface IZendeskIntegration {
|
||||
enable_software_vulnerabilities?: boolean;
|
||||
}
|
||||
|
||||
export interface IScepIntegration {
|
||||
export interface ICertificatesIntegrationNDES {
|
||||
url: string;
|
||||
admin_url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface ICertificatesIntegrationDigicert {
|
||||
id: number;
|
||||
name: string;
|
||||
api_token: string;
|
||||
profile_id: string;
|
||||
certificate_common_name: string;
|
||||
certificate_user_principal_names: string[];
|
||||
certificate_seat_id: string;
|
||||
}
|
||||
|
||||
export interface ICertificatesIntegrationCustomSCEP {
|
||||
id: number;
|
||||
name: string;
|
||||
server_url: string;
|
||||
challenge: string;
|
||||
}
|
||||
|
||||
export interface IIntegration {
|
||||
url: string;
|
||||
username?: string;
|
||||
@@ -91,7 +108,9 @@ export interface IZendeskJiraIntegrations {
|
||||
// Partial<IZendeskJiraIntegrations>`, but that leads to a mess of types to resolve.
|
||||
export interface IGlobalIntegrations extends IZendeskJiraIntegrations {
|
||||
google_calendar?: IGlobalCalendarIntegration[] | null;
|
||||
ndes_scep_proxy?: IScepIntegration | null;
|
||||
ndes_scep_proxy?: ICertificatesIntegrationNDES | null;
|
||||
digicert?: ICertificatesIntegrationDigicert[];
|
||||
custom_scep_proxy?: ICertificatesIntegrationCustomSCEP[];
|
||||
}
|
||||
|
||||
export interface ITeamIntegrations extends IZendeskJiraIntegrations {
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import React from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
const baseClass = "upload-list";
|
||||
|
||||
interface IUploadListProps {
|
||||
interface IUploadListProps<T = any> {
|
||||
/** The attribute name that is used for the react key for each list item */
|
||||
keyAttribute: string;
|
||||
listItems: any[]; // TODO: typings
|
||||
HeadingComponent?: (props: any) => JSX.Element; // TODO: Typings
|
||||
ListItemComponent: (props: { listItem: any }) => JSX.Element; // TODO: types
|
||||
sortCompareFn?: (a: any, b: any) => number;
|
||||
keyAttribute: keyof T;
|
||||
listItems: T[];
|
||||
HeadingComponent?: (props: any) => JSX.Element;
|
||||
ListItemComponent: (props: { listItem: T }) => JSX.Element;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const UploadList = ({
|
||||
const UploadList = <T,>({
|
||||
keyAttribute,
|
||||
listItems,
|
||||
HeadingComponent,
|
||||
ListItemComponent,
|
||||
sortCompareFn,
|
||||
}: IUploadListProps) => {
|
||||
className,
|
||||
}: IUploadListProps<T>) => {
|
||||
const items = listItems.map((listItem) => {
|
||||
return (
|
||||
<li
|
||||
@@ -28,16 +29,17 @@ const UploadList = ({
|
||||
</li>
|
||||
);
|
||||
});
|
||||
|
||||
const classNames = classnames(baseClass, className);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={classNames}>
|
||||
{HeadingComponent && (
|
||||
<div className={`${baseClass}__header`}>
|
||||
<HeadingComponent />
|
||||
</div>
|
||||
)}
|
||||
<ul className={`${baseClass}__list`}>
|
||||
{sortCompareFn ? items.sort(sortCompareFn) : items}
|
||||
</ul>
|
||||
<ul className={`${baseClass}__list`}>{items}</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import Integrations from "./cards/Integrations";
|
||||
import MdmSettings from "./cards/MdmSettings";
|
||||
import Calendars from "./cards/Calendars";
|
||||
import ChangeManagement from "./cards/ChangeManagement";
|
||||
import CertificateAuthorities from "./cards/CertificateAuthorities";
|
||||
|
||||
const integrationSettingsNavItems: ISideNavItem<any>[] = [
|
||||
// TODO: types
|
||||
@@ -32,6 +33,13 @@ const integrationSettingsNavItems: ISideNavItem<any>[] = [
|
||||
path: PATHS.ADMIN_INTEGRATIONS_CHANGE_MANAGEMENT,
|
||||
Card: ChangeManagement,
|
||||
},
|
||||
// TODO: digicert update: add this back when the feature is ready
|
||||
// {
|
||||
// title: "Certificates",
|
||||
// urlSection: "certificate-authorities",
|
||||
// path: PATHS.ADMIN_INTEGRATIONS_CERTIFICATE_AUTHORITIES,
|
||||
// Card: CertificateAuthorities,
|
||||
// },
|
||||
];
|
||||
|
||||
export default integrationSettingsNavItems;
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
import React, { useContext, useMemo, useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
|
||||
import paths from "router/paths";
|
||||
import { AppContext } from "context/app";
|
||||
import createMockConfig from "__mocks__/configMock";
|
||||
|
||||
import SectionHeader from "components/SectionHeader";
|
||||
import CustomLink from "components/CustomLink";
|
||||
|
||||
import CertificateAuthorityList from "./components/CertificateAuthorityList";
|
||||
import {
|
||||
generateListData,
|
||||
getCertificateAuthority,
|
||||
ICertAuthority,
|
||||
} from "./helpers";
|
||||
import AddCertAuthorityCard from "./components/AddCertAuthorityCard";
|
||||
|
||||
const baseClass = "certificate-authorities";
|
||||
|
||||
const CertificateAuthorities = () => {
|
||||
let { config } = useContext(AppContext);
|
||||
config = createMockConfig({
|
||||
integrations: {
|
||||
zendesk: [],
|
||||
jira: [],
|
||||
digicert: [
|
||||
{
|
||||
name: "DigiCert CA",
|
||||
id: 1,
|
||||
api_token: "123456",
|
||||
profile_id: "7ed77396-9186-4bfa-9fa7-63dddc46b8a3",
|
||||
certificate_common_name:
|
||||
"$FLEET_VAR_HOST_HARDWARE_SERIAL@example.com",
|
||||
certificate_user_principal_names: ["$FLEET_VAR_HOST_HARDWARE_SERIAL"],
|
||||
certificate_seat_id: "$FLEET_VAR_HOST_HARDWARE_SERIAL@example.com",
|
||||
},
|
||||
],
|
||||
ndes_scep_proxy: {
|
||||
url: "https://ndes.scep.com",
|
||||
admin_url: "https://ndes.scep.com/admin",
|
||||
username: "ndes",
|
||||
password: "password",
|
||||
},
|
||||
custom_scep_proxy: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Custom SCEP Proxy",
|
||||
server_url: "https://custom.scep.com",
|
||||
challenge: "challenge",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Custom SCEP Proxy 2",
|
||||
server_url: "https://custom.scep2.com",
|
||||
challenge: "challenge-2",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const [showAddCertAuthorityModal, setShowAddCertAuthorityModal] = useState(
|
||||
false
|
||||
);
|
||||
const [showEditCertAuthorityModal, setShowEditCertAuthorityModal] = useState(
|
||||
false
|
||||
);
|
||||
const [
|
||||
showDeleteCertAuthoirtyModal,
|
||||
setShowDeleteCertAuthorityModal,
|
||||
] = useState(false);
|
||||
|
||||
const certificateAuthorities = useMemo(() => {
|
||||
if (!config) return [];
|
||||
return generateListData(
|
||||
config?.integrations.ndes_scep_proxy,
|
||||
config?.integrations.digicert,
|
||||
config?.integrations.custom_scep_proxy
|
||||
);
|
||||
}, [config]);
|
||||
|
||||
const onAddCertAuthority = () => {
|
||||
setShowAddCertAuthorityModal(true);
|
||||
};
|
||||
|
||||
const onEditCertAuthority = (cert: ICertAuthority) => {
|
||||
// TODO: use useCallback
|
||||
const ca = getCertificateAuthority(
|
||||
cert.id,
|
||||
config?.integrations.ndes_scep_proxy,
|
||||
config?.integrations.digicert,
|
||||
config?.integrations.custom_scep_proxy
|
||||
);
|
||||
console.log(ca);
|
||||
setShowEditCertAuthorityModal(true);
|
||||
};
|
||||
|
||||
const onDeleteCertAuthority = (cert: ICertAuthority) => {
|
||||
// TODO: use useCallback
|
||||
getCertificateAuthority(
|
||||
cert.id,
|
||||
config?.integrations.ndes_scep_proxy,
|
||||
config?.integrations.digicert,
|
||||
config?.integrations.custom_scep_proxy
|
||||
);
|
||||
setShowDeleteCertAuthorityModal(true);
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
if (certificateAuthorities.length === 0) {
|
||||
return <AddCertAuthorityCard onAddCertAuthority={onAddCertAuthority} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<CertificateAuthorityList
|
||||
certAuthorities={certificateAuthorities}
|
||||
onAddCertAuthority={onAddCertAuthority}
|
||||
onClickEdit={onEditCertAuthority}
|
||||
onClickDelete={onDeleteCertAuthority}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<SectionHeader title="Certificates" />
|
||||
<p className={`${baseClass}__page-description`}>
|
||||
To help your end users connect to Wi-Fi or VPNs, you can add your
|
||||
certificate authority. Then, head over to{" "}
|
||||
<Link to={paths.CONTROLS_CUSTOM_SETTINGS}>
|
||||
Controls {">"} OS Settings {">"} Custom
|
||||
</Link>{" "}
|
||||
settings to configure how certificates are delivered to your hosts.{" "}
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url="https://fleetdm.com/learn-more-about/certificate-authorities"
|
||||
newTab
|
||||
/>
|
||||
</p>
|
||||
{renderContent()}
|
||||
{showAddCertAuthorityModal && <div>Modal showing</div>}
|
||||
{showEditCertAuthorityModal && <div>Modal showing</div>}
|
||||
{showDeleteCertAuthoirtyModal && <div>Modal showing</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CertificateAuthorities;
|
||||
@@ -0,0 +1,6 @@
|
||||
.certificate-authorities {
|
||||
|
||||
&__page-description {
|
||||
margin: 0 0 $pad-xlarge;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import React from "react";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
import Card from "components/Card";
|
||||
import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper";
|
||||
|
||||
const baseClass = "add-cert-authority-card";
|
||||
|
||||
interface IAddCertAuthoityCardProps {
|
||||
onAddCertAuthority: () => void;
|
||||
}
|
||||
|
||||
const AddCertAuthorityCard = ({
|
||||
onAddCertAuthority,
|
||||
}: IAddCertAuthoityCardProps) => {
|
||||
return (
|
||||
<Card paddingSize="xxlarge" className={baseClass}>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<p className={`${baseClass}__title`}>
|
||||
Add your certificate authority (CA)
|
||||
</p>
|
||||
<p>Help your end users connect to Wi-Fi or VPNs.</p>
|
||||
</div>
|
||||
<GitOpsModeTooltipWrapper
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
disabled={disableChildren}
|
||||
className={`${baseClass}__button`}
|
||||
onClick={onAddCertAuthority}
|
||||
>
|
||||
Add CA
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddCertAuthorityCard;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
.add-cert-authority-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: $pad-medium;
|
||||
|
||||
&__content {
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: $small;
|
||||
font-weight: $bold;
|
||||
margin-bottom: $pad-small;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./AddCertAuthorityCard";
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import Button from "components/buttons/Button";
|
||||
import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper";
|
||||
import Icon from "components/Icon";
|
||||
import React from "react";
|
||||
|
||||
const baseClass = "cert-authority-list-header";
|
||||
|
||||
interface ICertAuthorityListHeaderProps {
|
||||
onClickAddCertAuthority: () => void;
|
||||
}
|
||||
|
||||
const CertAuthorityListHeader = ({
|
||||
onClickAddCertAuthority,
|
||||
}: ICertAuthorityListHeaderProps) => {
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<span className={`${baseClass}__name`}>Certificate authority (CA)</span>
|
||||
<span className={`${baseClass}__actions`}>
|
||||
<GitOpsModeTooltipWrapper
|
||||
position="left"
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
disabled={disableChildren}
|
||||
variant="text-icon"
|
||||
className={`${baseClass}__add-button`}
|
||||
onClick={onClickAddCertAuthority}
|
||||
>
|
||||
<span className={`${baseClass}__btn-label`}>
|
||||
<Icon name="plus" />
|
||||
<span>Add CA</span>
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CertAuthorityListHeader;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
.cert-authority-list-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&__name {
|
||||
font-size: $x-small;
|
||||
font-weight: $bold;
|
||||
}
|
||||
|
||||
&__btn-label {
|
||||
display: flex;
|
||||
gap: $pad-small;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./CertAuthorityListHeader";
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
import React from "react";
|
||||
|
||||
import ListItem from "components/ListItem";
|
||||
import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper";
|
||||
import Button from "components/buttons/Button";
|
||||
import Icon from "components/Icon";
|
||||
|
||||
import { ICertAuthority } from "../../helpers";
|
||||
|
||||
const baseClass = "cert-authority-list-item";
|
||||
|
||||
interface IActionsProps {
|
||||
onEdit: () => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
const Actions = ({ onEdit, onDelete }: IActionsProps) => {
|
||||
return (
|
||||
<>
|
||||
<GitOpsModeTooltipWrapper
|
||||
position="left"
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
disabled={disableChildren}
|
||||
onClick={onEdit}
|
||||
className={`${baseClass}__action-button`}
|
||||
variant="text-icon"
|
||||
>
|
||||
<Icon name="pencil" color="ui-fleet-black-75" />
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<GitOpsModeTooltipWrapper
|
||||
position="left"
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
disabled={disableChildren}
|
||||
onClick={onDelete}
|
||||
className={`${baseClass}__action-button`}
|
||||
variant="text-icon"
|
||||
>
|
||||
<Icon name="trash" color="ui-fleet-black-75" />
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface ICertAuthorityListItemProps {
|
||||
cert: ICertAuthority;
|
||||
onClickEdit: () => void;
|
||||
onClickDelete: () => void;
|
||||
}
|
||||
|
||||
const CertAuthorityListItem = ({
|
||||
cert,
|
||||
onClickEdit,
|
||||
onClickDelete,
|
||||
}: ICertAuthorityListItemProps) => {
|
||||
return (
|
||||
<ListItem
|
||||
className={`${baseClass}__list-item`}
|
||||
graphic="file-certificate"
|
||||
title={cert.name}
|
||||
details={cert.name}
|
||||
actions={<Actions onEdit={onClickEdit} onDelete={onClickDelete} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CertAuthorityListItem;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
.cert-authority-list-item {
|
||||
&__action-button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./CertAuthorityListItem";
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import React from "react";
|
||||
|
||||
import UploadList from "pages/ManageControlsPage/components/UploadList";
|
||||
|
||||
import CertAuthorityListHeader from "../CertAuthorityListHeader";
|
||||
import CertAuthorityListItem from "../CertAuthorityListItem";
|
||||
import { ICertAuthority } from "../../helpers";
|
||||
|
||||
const baseClass = "certificate-authority-list";
|
||||
|
||||
interface ICertificateAuthorityListProps {
|
||||
certAuthorities: ICertAuthority[];
|
||||
onAddCertAuthority: () => void;
|
||||
onClickEdit: (cert: ICertAuthority) => void;
|
||||
onClickDelete: (cert: ICertAuthority) => void;
|
||||
}
|
||||
|
||||
const CertificateAuthorityList = ({
|
||||
certAuthorities,
|
||||
onAddCertAuthority,
|
||||
onClickEdit,
|
||||
onClickDelete,
|
||||
}: ICertificateAuthorityListProps) => {
|
||||
return (
|
||||
<UploadList<ICertAuthority>
|
||||
className={baseClass}
|
||||
keyAttribute="name"
|
||||
listItems={certAuthorities}
|
||||
HeadingComponent={() => (
|
||||
<CertAuthorityListHeader onClickAddCertAuthority={onAddCertAuthority} />
|
||||
)}
|
||||
ListItemComponent={({ listItem }) => (
|
||||
<CertAuthorityListItem
|
||||
cert={listItem}
|
||||
onClickEdit={() => onClickEdit(listItem)}
|
||||
onClickDelete={() => onClickDelete(listItem)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CertificateAuthorityList;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.certificate-authority-list {
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./CertificateAuthorityList";
|
||||
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
ICertificatesIntegrationCustomSCEP,
|
||||
ICertificatesIntegrationDigicert,
|
||||
ICertificatesIntegrationNDES,
|
||||
} from "interfaces/integration";
|
||||
|
||||
export interface ICertAuthority {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const generateListData = (
|
||||
ndesProxy?: ICertificatesIntegrationNDES | null,
|
||||
digicertCerts?: ICertificatesIntegrationDigicert[],
|
||||
customProxies?: ICertificatesIntegrationCustomSCEP[]
|
||||
) => {
|
||||
const listData: ICertAuthority[] = [];
|
||||
|
||||
// these values for the certificateAuthority is meant to be a hard coded .
|
||||
if (ndesProxy) {
|
||||
listData.push({
|
||||
id: "ndes", // only ever one NDES so no need to make the id dynamic
|
||||
name: "NDES",
|
||||
description: "Microsoft Network Device Enrollment Service (NDES)",
|
||||
});
|
||||
}
|
||||
|
||||
if (digicertCerts?.length) {
|
||||
digicertCerts.forEach((cert) => {
|
||||
listData.push({
|
||||
id: `digicert-${cert.id}`,
|
||||
name: cert.name,
|
||||
description: "DigiCert",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (customProxies?.length) {
|
||||
customProxies.forEach((cert) => {
|
||||
listData.push({
|
||||
id: `custom-scep-proxy-${cert.id}`,
|
||||
name: cert.name,
|
||||
description: "Custom Simple Certificate Enrollment Protocol (SCEP)",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return listData.sort((a, b) =>
|
||||
a.name.toLowerCase().localeCompare(b.name.toLocaleLowerCase())
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the original certificate aithority integration object from the id
|
||||
* of the data representing a certificate authority list item.
|
||||
*/
|
||||
export const getCertificateAuthority = (
|
||||
id: string,
|
||||
ncspProxy?: ICertificatesIntegrationNDES | null,
|
||||
digicertCerts?: ICertificatesIntegrationDigicert[],
|
||||
customProxies?: ICertificatesIntegrationCustomSCEP[]
|
||||
) => {
|
||||
if (id === "ndes") {
|
||||
return ncspProxy as ICertificatesIntegrationNDES;
|
||||
}
|
||||
|
||||
if (id.includes("digicert")) {
|
||||
return digicertCerts?.find(
|
||||
(cert) => id.split("digicert-")[1] === cert.id.toString()
|
||||
);
|
||||
}
|
||||
|
||||
if (id.includes("custom-scep-proxy")) {
|
||||
return customProxies?.find(
|
||||
(cert) => id.split("custom-scep-proxy-")[1] === cert.id.toString()
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./CertificateAuthorities";
|
||||
@@ -133,6 +133,7 @@ const MdmSettings = ({ router }: IMdmSettingsProps) => {
|
||||
isVppOn={!noVppTokenUploaded}
|
||||
isPremiumTier={!!isPremiumTier}
|
||||
/>
|
||||
{/* TODO: digicert update: remove scep section when digicert feature is ready */}
|
||||
<ScepSection
|
||||
router={router}
|
||||
isScepOn={!noScepCredentials}
|
||||
|
||||
@@ -66,6 +66,7 @@ import WindowsMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/Windo
|
||||
import AppleMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage";
|
||||
import AndroidMdmPage from "pages/admin/IntegrationsPage/cards/MdmSettings/AndroidMdmPage";
|
||||
import ScepPage from "pages/admin/IntegrationsPage/cards/MdmSettings/ScepPage";
|
||||
import CertificatesPage from "pages/admin/IntegrationsPage/cards/CertificateAuthorities";
|
||||
import Scripts from "pages/ManageControlsPage/Scripts/Scripts";
|
||||
import WindowsAutomaticEnrollmentPage from "pages/admin/IntegrationsPage/cards/MdmSettings/WindowsAutomaticEnrollmentPage";
|
||||
import AppleBusinessManagerPage from "pages/admin/IntegrationsPage/cards/MdmSettings/AppleBusinessManagerPage";
|
||||
@@ -200,6 +201,7 @@ const routes = (
|
||||
<Route path="integrations/mdm/windows" component={WindowsMdmPage} />
|
||||
<Route path="integrations/mdm/apple" component={AppleMdmPage} />
|
||||
<Route path="integrations/mdm/android" component={AndroidMdmPage} />
|
||||
{/* TODO: digicert update: remove scep route when digicert feature is ready */}
|
||||
<Route path="integrations/mdm/scep" component={ScepPage} />
|
||||
{/* This redirect is used to handle old apple automatic enrollments page */}
|
||||
<Redirect
|
||||
|
||||
@@ -49,6 +49,7 @@ export default {
|
||||
ADMIN_INTEGRATIONS_SCEP: `${URL_PREFIX}/settings/integrations/mdm/scep`,
|
||||
ADMIN_INTEGRATIONS_CALENDARS: `${URL_PREFIX}/settings/integrations/calendars`,
|
||||
ADMIN_INTEGRATIONS_CHANGE_MANAGEMENT: `${URL_PREFIX}/settings/integrations/change-management`,
|
||||
ADMIN_INTEGRATIONS_CERTIFICATE_AUTHORITIES: `${URL_PREFIX}/settings/integrations/certificate-authorities`,
|
||||
ADMIN_INTEGRATIONS_VPP: `${URL_PREFIX}/settings/integrations/mdm/vpp`,
|
||||
ADMIN_INTEGRATIONS_VPP_SETUP: `${URL_PREFIX}/settings/integrations/vpp/setup`,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user