import { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { format } from "date-fns"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; import { Button, FormControl, Input, Modal, ModalContent, Select, SelectItem, Switch // DatePicker } from "@app/components/v2"; import { useWorkspace } from "@app/context"; import { CaStatus, CaType, InternalCaType, useCreateCa, useGetCa, useUpdateCa } from "@app/hooks/api/ca"; import { certKeyAlgorithms } from "@app/hooks/api/certificates/constants"; import { CertKeyAlgorithm } from "@app/hooks/api/certificates/enums"; import { UsePopUpState } from "@app/hooks/usePopUp"; import { slugSchema } from "@app/lib/schemas"; const isValidDate = (dateString: string) => { const date = new Date(dateString); return !Number.isNaN(date.getTime()); }; const getDateTenYearsFromToday = () => { const date = new Date(); date.setFullYear(date.getFullYear() + 10); return format(date, "yyyy-MM-dd"); }; const schema = z .object({ type: z.nativeEnum(CaType), name: slugSchema({ field: "Name" }), enableDirectIssuance: z.boolean(), status: z.nativeEnum(CaStatus), configuration: z .object({ type: z.enum([InternalCaType.ROOT, InternalCaType.INTERMEDIATE]), organization: z.string(), ou: z.string(), country: z.string(), province: z.string(), locality: z.string(), commonName: z.string(), notAfter: z.string().trim().refine(isValidDate, { message: "Invalid date format" }), maxPathLength: z.string(), keyAlgorithm: z.enum([ CertKeyAlgorithm.RSA_2048, CertKeyAlgorithm.RSA_4096, CertKeyAlgorithm.ECDSA_P256, CertKeyAlgorithm.ECDSA_P384 ]) }) .required() }) .required(); export type FormData = z.infer; type Props = { popUp: UsePopUpState<["ca"]>; handlePopUpToggle: (popUpName: keyof UsePopUpState<["ca"]>, state?: boolean) => void; }; const caTypes = [ { label: "Root", value: InternalCaType.ROOT }, { label: "Intermediate", value: InternalCaType.INTERMEDIATE } ]; export const CaModal = ({ popUp, handlePopUpToggle }: Props) => { const { currentWorkspace } = useWorkspace(); const { data: ca } = useGetCa({ caName: (popUp?.ca?.data as { name: string })?.name || "", projectId: currentWorkspace?.id || "", type: CaType.INTERNAL }); const { mutateAsync: createMutateAsync } = useCreateCa(); const { mutateAsync: updateMutateAsync } = useUpdateCa(); const { control, handleSubmit, reset, formState: { isSubmitting }, watch } = useForm({ resolver: zodResolver(schema), defaultValues: { type: CaType.INTERNAL, name: "", status: CaStatus.ACTIVE, enableDirectIssuance: true, configuration: { type: InternalCaType.ROOT, organization: "", ou: "", country: "", province: "", locality: "", commonName: "", notAfter: getDateTenYearsFromToday(), maxPathLength: "-1", keyAlgorithm: CertKeyAlgorithm.RSA_2048 } } }); const caType = watch("configuration.type"); useEffect(() => { if (ca && ca.type === CaType.INTERNAL) { reset({ type: ca.type, name: ca.name, status: ca.status, enableDirectIssuance: ca.enableDirectIssuance, configuration: { type: ca.configuration.type, organization: ca.configuration.organization, ou: ca.configuration.ou, country: ca.configuration.country, province: ca.configuration.province, locality: ca.configuration.locality, commonName: ca.configuration.commonName, notAfter: ca.configuration.notAfter ? format(new Date(ca.configuration.notAfter), "yyyy-MM-dd") : "", maxPathLength: ca.configuration.maxPathLength ? String(ca.configuration.maxPathLength) : "", keyAlgorithm: ca.configuration.keyAlgorithm } }); } else { reset({ type: CaType.INTERNAL, name: "", status: CaStatus.ACTIVE, enableDirectIssuance: true, configuration: { type: InternalCaType.ROOT, organization: "", ou: "", country: "", province: "", locality: "", commonName: "", notAfter: getDateTenYearsFromToday(), maxPathLength: "-1", keyAlgorithm: CertKeyAlgorithm.RSA_2048 } }); } }, [ca]); const onFormSubmit = async ({ type, name, enableDirectIssuance, status, configuration }: FormData) => { try { if (!currentWorkspace?.slug) return; if (ca) { // update await updateMutateAsync({ caName: ca.name, projectId: currentWorkspace.id, name, type: CaType.INTERNAL, status, enableDirectIssuance }); } else { // create await createMutateAsync({ projectId: currentWorkspace.id, name, type, status, enableDirectIssuance, configuration: { ...configuration, maxPathLength: Number(configuration.maxPathLength) } }); } reset(); handlePopUpToggle("ca", false); createNotification({ text: `Successfully ${ca ? "updated" : "created"} CA`, type: "success" }); } catch (err) { console.error(err); createNotification({ text: "Failed to create CA", type: "error" }); } }; return ( { reset(); handlePopUpToggle("ca", isOpen); }} >
{ca && ( )} ( )} /> {caType === InternalCaType.ROOT && ( <> {/* { return ( { onChange(date); setIsStartDatePickerOpen(false); }} popUpProps={{ open: isStartDatePickerOpen, onOpenChange: setIsStartDatePickerOpen }} popUpContentProps={{}} /> ); }} /> */} ( )} /> ( )} /> )} ( )} /> ( )} /> ( )} /> ( )} /> ( )} /> ( )} /> ( )} /> ( )} /> { return ( field.onChange(value)} isChecked={field.value} >

Enable Direct Issuance

); }} />
); };