import React from 'react'; import { IconCertificate, IconTrash, IconWorld } from '@tabler/icons'; import { useFormik } from 'formik'; import * as Yup from 'yup'; import StyledWrapper from './StyledWrapper'; import { useRef } from 'react'; import path from 'utils/common/path'; import SensitiveFieldWarning from 'components/SensitiveFieldWarning/index'; import SingleLineEditor from 'components/SingleLineEditor/index'; import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField/index'; import { useTheme } from 'styled-components'; import { useDispatch } from 'react-redux'; import { updateCollectionClientCertificates } from 'providers/ReduxStore/slices/collections'; import { saveCollectionSettings } from 'providers/ReduxStore/slices/collections/actions'; import get from 'lodash/get'; const ClientCertSettings = ({ collection }) => { const dispatch = useDispatch(); // Get client certs from draft if exists, otherwise from brunoConfig const clientCertConfig = collection.draft?.brunoConfig ? get(collection, 'draft.brunoConfig.clientCertificates.certs', []) : get(collection, 'brunoConfig.clientCertificates.certs', []); const certFilePathInputRef = useRef(); const keyFilePathInputRef = useRef(); const pfxFilePathInputRef = useRef(); const { storedTheme } = useTheme(); const formik = useFormik({ initialValues: { domain: '', type: 'cert', certFilePath: '', keyFilePath: '', pfxFilePath: '', passphrase: '' }, validationSchema: Yup.object({ domain: Yup.string() .required() .trim() .test('not-empty-after-trim', 'Domain is required', (value) => value && value.trim().length > 0), type: Yup.string().required().oneOf(['cert', 'pfx']), certFilePath: Yup.string().when('type', { is: (type) => type == 'cert', then: Yup.string().min(1, 'certFilePath is a required field').required() }), keyFilePath: Yup.string().when('type', { is: (type) => type == 'cert', then: Yup.string().min(1, 'keyFilePath is a required field').required() }), pfxFilePath: Yup.string().when('type', { is: (type) => type == 'pfx', then: Yup.string().min(1, 'pfxFilePath is a required field').required() }), passphrase: Yup.string() }), onSubmit: (values) => { let relevantValues = {}; if (values.type === 'cert') { relevantValues = { domain: values.domain?.trim(), type: values.type, certFilePath: values.certFilePath, keyFilePath: values.keyFilePath, passphrase: values.passphrase }; } else { relevantValues = { domain: values.domain?.trim(), type: values.type, pfxFilePath: values.pfxFilePath, passphrase: values.passphrase }; } // Add the new cert to the existing certs in draft const updatedCerts = [...clientCertConfig, relevantValues]; const clientCertificates = { enabled: true, certs: updatedCerts }; dispatch(updateCollectionClientCertificates({ collectionUid: collection.uid, clientCertificates })); formik.resetForm(); resetFileInputFields(); } }); const { isSensitive } = useDetectSensitiveField(collection); const { showWarning, warningMessage } = isSensitive(formik.values.passphrase); const getFile = (e) => { const filePath = window?.ipcRenderer?.getFilePath(e?.files?.[0]); if (filePath) { let relativePath = path.relative(collection.pathname, filePath); formik.setFieldValue(e.name, relativePath); } }; const resetFileInputFields = () => { if (certFilePathInputRef.current) { certFilePathInputRef.current.value = ''; } if (keyFilePathInputRef.current) { keyFilePathInputRef.current.value = ''; } if (pfxFilePathInputRef.current) { pfxFilePathInputRef.current.value = ''; } }; const handleTypeChange = (e) => { formik.setFieldValue('type', e.target.value); if (e.target.value === 'cert') { formik.setFieldValue('pfxFilePath', ''); pfxFilePathInputRef.current.value = ''; } else { formik.setFieldValue('certFilePath', ''); certFilePathInputRef.current.value = ''; formik.setFieldValue('keyFilePath', ''); keyFilePathInputRef.current.value = ''; } }; const handleRemove = (indexToRemove) => { const updatedCerts = clientCertConfig.filter((cert, index) => index !== indexToRemove); const clientCertificates = { enabled: true, certs: updatedCerts }; dispatch(updateCollectionClientCertificates({ collectionUid: collection.uid, clientCertificates })); }; const handleSave = () => dispatch(saveCollectionSettings(collection.uid)); return (
Add client certificates to be used for specific domains.

Client Certificates

Add Client Certificate

https:// grpcs:// wss://
{formik.touched.domain && formik.errors.domain ? (
{formik.errors.domain}
) : null}
{formik.values.type === 'cert' ? ( <>
getFile(e.target)} ref={certFilePathInputRef} /> {formik.values.certFilePath ? (
{path.basename(formik.values.certFilePath)}
{ formik.setFieldValue('certFilePath', ''); certFilePathInputRef.current.value = ''; }} />
) : ( <> )}
{formik.touched.certFilePath && formik.errors.certFilePath ? (
{formik.errors.certFilePath}
) : null}
getFile(e.target)} ref={keyFilePathInputRef} /> {formik.values.keyFilePath ? (
{path.basename(formik.values.keyFilePath)}
{ formik.setFieldValue('keyFilePath', ''); keyFilePathInputRef.current.value = ''; }} />
) : ( <> )}
{formik.touched.keyFilePath && formik.errors.keyFilePath ? (
{formik.errors.keyFilePath}
) : null}
) : ( <>
getFile(e.target)} ref={pfxFilePathInputRef} /> {formik.values.pfxFilePath ? (
{path.basename(formik.values.pfxFilePath)}
{ formik.setFieldValue('pfxFilePath', ''); pfxFilePathInputRef.current.value = ''; }} />
) : ( <> )}
{formik.touched.pfxFilePath && formik.errors.pfxFilePath ? (
{formik.errors.pfxFilePath}
) : null}
)}
formik.setFieldValue('passphrase', val)} collection={collection} isSecret={true} /> {showWarning && }
{formik.touched.passphrase && formik.errors.passphrase ? (
{formik.errors.passphrase}
) : null}
); }; export default ClientCertSettings;