TLS Certificate React component (#1780)
Add support to parse multiple blocks on pem certificate Added react tls certificate component Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
@@ -572,32 +572,44 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
|
||||
}
|
||||
// Extract public key from certificate TLS secret
|
||||
if rawCert, ok := keyPair.Data[publicKey]; ok {
|
||||
block, _ := pem.Decode(rawCert)
|
||||
if block == nil {
|
||||
// If certificate failed to decode skip
|
||||
continue
|
||||
var blocks []byte
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, rawCert = pem.Decode(rawCert)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type == "CERTIFICATE" {
|
||||
blocks = append(blocks, block.Bytes...)
|
||||
}
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
// parse all certificates we found on this k8s secret
|
||||
certs, err := x509.ParseCertificates(blocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domains := []string{}
|
||||
// append certificate domain names
|
||||
if len(cert.DNSNames) > 0 {
|
||||
domains = append(domains, cert.DNSNames...)
|
||||
}
|
||||
// append certificate IPs
|
||||
if len(cert.IPAddresses) > 0 {
|
||||
for _, ip := range cert.IPAddresses {
|
||||
domains = append(domains, ip.String())
|
||||
for _, cert := range certs {
|
||||
var domains []string
|
||||
if cert.Subject.CommonName != "" {
|
||||
domains = append(domains, cert.Subject.CommonName)
|
||||
}
|
||||
// append certificate domain names
|
||||
if len(cert.DNSNames) > 0 {
|
||||
domains = append(domains, cert.DNSNames...)
|
||||
}
|
||||
// append certificate IPs
|
||||
if len(cert.IPAddresses) > 0 {
|
||||
for _, ip := range cert.IPAddresses {
|
||||
domains = append(domains, ip.String())
|
||||
}
|
||||
}
|
||||
certificates = append(certificates, &models.CertificateInfo{
|
||||
SerialNumber: cert.SerialNumber.String(),
|
||||
Name: secret.Name,
|
||||
Domains: domains,
|
||||
Expiry: cert.NotAfter.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
certificates = append(certificates, &models.CertificateInfo{
|
||||
SerialNumber: cert.SerialNumber.String(),
|
||||
Name: secret.Name,
|
||||
Domains: domains,
|
||||
Expiry: cert.NotAfter.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
}
|
||||
return certificates, nil
|
||||
@@ -627,8 +639,6 @@ func getTenantSecurityResponse(session *models.Principal, params operator_api.Te
|
||||
// 5 seconds timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
//defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
|
||||
57
portal-ui/src/icons/CertificateIcon.tsx
Normal file
57
portal-ui/src/icons/CertificateIcon.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import * as React from "react";
|
||||
import { SVGProps } from "react";
|
||||
|
||||
const CertificateIcon = (props: SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="certificate_svg__a">
|
||||
<path
|
||||
data-name="Rect\xE1ngulo 2156"
|
||||
fill="#07193e"
|
||||
d="M0 0h256v222.048H0z"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
data-name="Grupo 4763"
|
||||
transform="translate(0 17)"
|
||||
clipPath="url(#certificate_svg__a)"
|
||||
fill="#07193e"
|
||||
>
|
||||
<path
|
||||
data-name="Trazado 8152"
|
||||
d="M240-.002H16a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h120l4.64-5.6 7.44-9.12A66.72 66.72 0 0 1 256 98.958v-82.96a16 16 0 0 0-16-16m-130.96 149.7H47.3a7.3 7.3 0 1 1 0-14.592h61.74a7.3 7.3 0 1 1 0 14.592m0-56H47.3a7.3 7.3 0 1 1 0-14.592h61.74a7.3 7.3 0 0 1 0 14.592m66.96-39.3a6.419 6.419 0 0 1-6.4 6.4H46.4a6.419 6.419 0 0 1-6.4-6.4v-1.792a6.419 6.419 0 0 1 6.4-6.4h123.2a6.419 6.419 0 0 1 6.4 6.4Z"
|
||||
/>
|
||||
<path
|
||||
data-name="Trazado 8153"
|
||||
d="M256 137.486a50.96 50.96 0 1 0-86.16 36.72l-15.52 18.96 7.2 28.88 29.28-35.68a50.018 50.018 0 0 0 28.4 0l29.28 35.68 7.2-28.88-15.52-18.96a50.75 50.75 0 0 0 15.84-36.72m-50.928 29.688a29.688 29.688 0 0 1-.072-59.376h.072a29.688 29.688 0 0 1 0 59.376"
|
||||
/>
|
||||
</g>
|
||||
<path data-name="Rect\xE1ngulo 2157" fill="none" d="M0 0h256v256H0z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
export default CertificateIcon;
|
||||
@@ -0,0 +1,171 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { ICertificateInfo } from "../../Tenants/types";
|
||||
import LanguageIcon from "@mui/icons-material/Language";
|
||||
import Chip from "@mui/material/Chip";
|
||||
import {
|
||||
Typography,
|
||||
Divider,
|
||||
Box,
|
||||
Grid,
|
||||
Container,
|
||||
ListItemText,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
} from "@mui/material";
|
||||
import EventBusyIcon from "@mui/icons-material/EventBusy";
|
||||
import Moment from "react-moment";
|
||||
import CertificateIcon from "../../../../icons/CertificateIcon";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
border: 0,
|
||||
backgroundColor: "transparent",
|
||||
textDecoration: "underline",
|
||||
cursor: "pointer",
|
||||
fontSize: "inherit",
|
||||
color: theme.palette.info.main,
|
||||
fontFamily: "Lato, sans-serif",
|
||||
},
|
||||
certificateIcon: {
|
||||
float: "left",
|
||||
paddingTop: "5px !important",
|
||||
paddingRight: "10px !important",
|
||||
},
|
||||
certificateInfo: { float: "right" },
|
||||
certificateWrapper: {
|
||||
height: "auto",
|
||||
margin: 5,
|
||||
border: "1px solid #E2E2E2",
|
||||
userSelect: "text",
|
||||
borderRadius: 4,
|
||||
"& h6": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
"& div": {
|
||||
padding: 0,
|
||||
},
|
||||
},
|
||||
certificateExpiry: {
|
||||
color: "#616161",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "wrap",
|
||||
marginBottom: 5,
|
||||
"& .label": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
certificateDomains: {
|
||||
color: "#616161",
|
||||
"& .label": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
certificatesList: {
|
||||
border: "1px solid #E2E2E2",
|
||||
borderRadius: 4,
|
||||
color: "#616161",
|
||||
textTransform: "lowercase",
|
||||
overflowY: "scroll",
|
||||
maxHeight: 145,
|
||||
marginBottom: 10,
|
||||
},
|
||||
certificatesListItem: {
|
||||
padding: "0px 16px",
|
||||
borderBottom: "1px solid #E2E2E2",
|
||||
"& div": {
|
||||
minWidth: 0,
|
||||
},
|
||||
"& svg": {
|
||||
fontSize: 12,
|
||||
marginRight: 10,
|
||||
opacity: 0.5,
|
||||
},
|
||||
"& span": {
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
interface ITLSCertificate {
|
||||
classes: any;
|
||||
certificateInfo: ICertificateInfo;
|
||||
onDelete: any;
|
||||
}
|
||||
|
||||
const TLSCertificate = ({
|
||||
classes,
|
||||
certificateInfo,
|
||||
onDelete = () => {},
|
||||
}: ITLSCertificate) => {
|
||||
const certificates = certificateInfo.domains || [];
|
||||
return (
|
||||
<Chip
|
||||
key={certificateInfo.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateWrapper}
|
||||
label={
|
||||
<Container>
|
||||
<Grid item xs={1} className={classes.certificateIcon}>
|
||||
<CertificateIcon />
|
||||
</Grid>
|
||||
<Grid item xs={11} className={classes.certificateInfo}>
|
||||
<Typography variant="subtitle1" display="block" gutterBottom>
|
||||
{certificateInfo.name}
|
||||
</Typography>
|
||||
<Box className={classes.certificateExpiry}>
|
||||
<EventBusyIcon color="inherit" fontSize="small" />
|
||||
|
||||
<span className={"label"}>Expiry: </span>
|
||||
<span>
|
||||
<Moment format="YYYY/MM/DD">{certificateInfo.expiry}</Moment>
|
||||
</span>
|
||||
</Box>
|
||||
<Divider />
|
||||
<br />
|
||||
<Box className={classes.certificateDomains}>
|
||||
<span className="label">{`${certificates.length} Domain (s):`}</span>
|
||||
</Box>
|
||||
<List className={classes.certificatesList}>
|
||||
{certificates.map((dom) => (
|
||||
<ListItem className={classes.certificatesListItem}>
|
||||
<ListItemAvatar>
|
||||
<LanguageIcon />
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={dom} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Grid>
|
||||
</Container>
|
||||
}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(TLSCertificate);
|
||||
@@ -46,9 +46,7 @@ import Grid from "@mui/material/Grid";
|
||||
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import { Button, DialogContentText, Typography } from "@mui/material";
|
||||
import Chip from "@mui/material/Chip";
|
||||
import Moment from "react-moment";
|
||||
import { Button, DialogContentText } from "@mui/material";
|
||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import { KeyPair } from "../ListTenants/utils";
|
||||
@@ -58,6 +56,7 @@ import {
|
||||
IValidation,
|
||||
} from "../../../../utils/validationFunctions";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate";
|
||||
|
||||
interface ITenantEncryption {
|
||||
classes: any;
|
||||
@@ -913,47 +912,8 @@ const TenantEncryption = ({
|
||||
Mutual TLS authentication with KMS (optional)
|
||||
</legend>
|
||||
{vaultClientCertificateSecret ? (
|
||||
<Chip
|
||||
key={vaultClientCertificateSecret.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{vaultClientCertificateSecret.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{vaultClientCertificateSecret.domains &&
|
||||
vaultClientCertificateSecret.domains.map(
|
||||
(dom) => {
|
||||
return <div>{dom}</div>;
|
||||
}
|
||||
)}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{vaultClientCertificateSecret.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={vaultClientCertificateSecret}
|
||||
onDelete={() =>
|
||||
removeCertificate(vaultClientCertificateSecret)
|
||||
}
|
||||
@@ -1002,47 +962,8 @@ const TenantEncryption = ({
|
||||
KMS CA certificate (optional)
|
||||
</legend>
|
||||
{vaultCACertificateSecret ? (
|
||||
<Chip
|
||||
key={vaultCACertificateSecret.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{vaultCACertificateSecret.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{vaultCACertificateSecret.domains &&
|
||||
vaultCACertificateSecret.domains.map(
|
||||
(dom) => {
|
||||
return <div>{dom}</div>;
|
||||
}
|
||||
)}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{vaultCACertificateSecret.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={vaultCACertificateSecret}
|
||||
onDelete={() =>
|
||||
removeCertificate(vaultCACertificateSecret)
|
||||
}
|
||||
@@ -1617,47 +1538,8 @@ const TenantEncryption = ({
|
||||
value={""}
|
||||
/>
|
||||
{gemaltoCACertificateSecret ? (
|
||||
<Chip
|
||||
key={gemaltoCACertificateSecret.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{gemaltoCACertificateSecret.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{gemaltoCACertificateSecret.domains &&
|
||||
gemaltoCACertificateSecret.domains.map(
|
||||
(dom) => {
|
||||
return <div>{dom}</div>;
|
||||
}
|
||||
)}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{gemaltoCACertificateSecret.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={gemaltoCACertificateSecret}
|
||||
onDelete={() =>
|
||||
removeCertificate(gemaltoCACertificateSecret)
|
||||
}
|
||||
@@ -1709,47 +1591,8 @@ const TenantEncryption = ({
|
||||
Encryption Service Certificates
|
||||
</legend>
|
||||
{serverTLSCertificateSecret ? (
|
||||
<Chip
|
||||
key={serverTLSCertificateSecret.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{serverTLSCertificateSecret.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{serverTLSCertificateSecret.domains &&
|
||||
serverTLSCertificateSecret.domains.map(
|
||||
(dom) => {
|
||||
return <div>{dom}</div>;
|
||||
}
|
||||
)}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{serverTLSCertificateSecret.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={serverTLSCertificateSecret}
|
||||
onDelete={() =>
|
||||
removeCertificate(serverTLSCertificateSecret)
|
||||
}
|
||||
@@ -1804,45 +1647,8 @@ const TenantEncryption = ({
|
||||
Mutual TLS authentication with MinIO
|
||||
</legend>
|
||||
{mTLSCertificateSecret ? (
|
||||
<Chip
|
||||
key={mTLSCertificateSecret.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{mTLSCertificateSecret.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{mTLSCertificateSecret.domains &&
|
||||
mTLSCertificateSecret.domains.map((dom) => {
|
||||
return <div>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{mTLSCertificateSecret.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={mTLSCertificateSecret}
|
||||
onDelete={() =>
|
||||
removeCertificate(mTLSCertificateSecret)
|
||||
}
|
||||
|
||||
@@ -26,11 +26,9 @@ import {
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Chip from "@mui/material/Chip";
|
||||
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
||||
import Moment from "react-moment";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import { Button, DialogContentText, Typography } from "@mui/material";
|
||||
import { Button, DialogContentText } from "@mui/material";
|
||||
import { KeyPair } from "../ListTenants/utils";
|
||||
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
|
||||
import api from "../../../../common/api";
|
||||
@@ -42,6 +40,7 @@ import { setTenantDetailsLoad } from "../actions";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import { AddIcon, ConfirmModalIcon } from "../../../../icons";
|
||||
import Loader from "../../Common/Loader/Loader";
|
||||
import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate";
|
||||
|
||||
interface ITenantSecurity {
|
||||
classes: any;
|
||||
@@ -66,10 +65,6 @@ const styles = (theme: Theme) =>
|
||||
paperContainer: {
|
||||
padding: "15px 15px 15px 50px",
|
||||
},
|
||||
certificateInfo: {
|
||||
height: "auto",
|
||||
margin: 5,
|
||||
},
|
||||
fileItem: {
|
||||
marginRight: 10,
|
||||
display: "flex",
|
||||
@@ -388,45 +383,8 @@ const TenantSecurity = ({
|
||||
<Grid container item xs={12}>
|
||||
{minioTLSCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<Chip
|
||||
key={certificateInfo.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return <div key={`domain-${dom}`}>{dom}</div>;
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{certificateInfo.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
/>
|
||||
)
|
||||
@@ -508,47 +466,8 @@ const TenantSecurity = ({
|
||||
<Grid container item xs={12}>
|
||||
{minioTLSCaCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<Chip
|
||||
key={certificateInfo.name}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
className={classes.certificateInfo}
|
||||
label={
|
||||
<div>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.italic}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
{certificateInfo.domains &&
|
||||
certificateInfo.domains.map((dom) => {
|
||||
return (
|
||||
<div key={`CA-domain-${dom}`}>{dom}</div>
|
||||
);
|
||||
})}
|
||||
</Typography>
|
||||
<Typography
|
||||
className={classes.bold}
|
||||
variant="overline"
|
||||
gutterBottom
|
||||
>
|
||||
Expiry:
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
<Moment format="YYYY-MM-DD">
|
||||
{certificateInfo.expiry}
|
||||
</Moment>
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
/>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user