diff --git a/frontend/package.json b/frontend/package.json index a444b4d3..1a057f54 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ "@types/styled-components": "5.1.25", "@typescript-eslint/eslint-plugin": "^5.30.6", "@typescript-eslint/parser": "^5.30.6", + "ajv": "^8.12.0", "babel-eslint": "^10.1.0", "classnames": "^2.3.1", "country-flag-icons": "^1.5.5", diff --git a/frontend/src/modals/DNSProviderCreateModal.tsx b/frontend/src/modals/DNSProviderCreateModal.tsx index f8e39f50..6963f94b 100644 --- a/frontend/src/modals/DNSProviderCreateModal.tsx +++ b/frontend/src/modals/DNSProviderCreateModal.tsx @@ -18,13 +18,14 @@ import { Stack, useToast, } from "@chakra-ui/react"; +import Ajv, { Schema } from "ajv"; import { DNSProvider, DNSProvidersAcmesh, DNSProvidersAcmeshProperty, } from "api/npm"; import { PrettyButton } from "components"; -import { Formik, Form, Field } from "formik"; +import { Formik, Form, Field, getIn } from "formik"; import { useSetDNSProvider, useDNSProvidersAcmesh } from "hooks"; import { intl } from "locale"; import { validateString } from "modules/Validations"; @@ -39,12 +40,8 @@ function DNSProviderCreateModal({ }: DNSProviderCreateModalProps) { const toast = useToast(); const { mutate: setDNSProvider } = useSetDNSProvider(); - const { - isLoading: acmeshIsLoading, - // isError: acmeshIsError, - // error: acmeshError, - data: acmeshDataResp, - } = useDNSProvidersAcmesh(); + const { isLoading: acmeshIsLoading, data: acmeshDataResp } = + useDNSProvidersAcmesh(); const [acmeshData, setAcmeshData] = useState([] as DNSProvidersAcmesh[]); const [acmeshItem, setAcmeshItem] = useState(""); @@ -58,13 +55,17 @@ function DNSProviderCreateModal({ onClose(); }; + const getAcmeshItem = (name: string): DNSProvidersAcmesh | undefined => { + return acmeshData.find((item) => item.title === name); + }; + + const fullItem = getAcmeshItem(acmeshItem); + const itemProperties = fullItem?.properties; + const onSubmit = async ( payload: DNSProvider, { setErrors, setSubmitting }: any, ) => { - // TODO: filter out the meta object and only include items that apply to the acmesh provider selected - console.log("PAYLOAD:", payload); - const showErr = (msg: string) => { toast({ description: intl.formatMessage({ @@ -77,30 +78,42 @@ function DNSProviderCreateModal({ }); }; - setDNSProvider(payload, { - onError: (err: any) => { - if (err.message === "ca-bundle-does-not-exist") { - setErrors({ - caBundle: intl.formatMessage({ - id: `error.${err.message}`, - }), - }); - } else { - showErr(err.message); - } - }, - onSuccess: () => onModalClose(), - onSettled: () => setSubmitting(false), - }); + const ajv = new Ajv({ strictSchema: false }); + try { + const valid = ajv.validate(fullItem as Schema, payload.meta); + if (!valid) { + let errs: any = {}; + ajv.errors?.forEach((e: any) => { + errs["meta"] = { + [e.instancePath.substring(1)]: e.message, + }; + }); + setErrors(errs); + setSubmitting(false); + } else { + // Json schema is happy + setDNSProvider(payload, { + onError: (err: any) => { + if (err.message === "ca-bundle-does-not-exist") { + setErrors({ + caBundle: intl.formatMessage({ + id: `error.${err.message}`, + }), + }); + } else { + showErr(err.message); + } + }, + onSuccess: () => onModalClose(), + onSettled: () => setSubmitting(false), + }); + } + } catch (err: any) { + showErr(err); + setSubmitting(false); + } }; - const getAcmeshItem = (name: string): DNSProvidersAcmesh | undefined => { - return acmeshData.find((item) => item.title === name); - }; - - const fullItem = getAcmeshItem(acmeshItem); - const itemProperties = fullItem?.properties; - const renderInputType = ( field: any, fieldName: string, @@ -250,7 +263,8 @@ function DNSProviderCreateModal({ ) !== -1 } isInvalid={ - form.errors[name] && form.touched[name] + getIn(form.errors, name) && + getIn(form.touched, name) }> {f.type !== "bool" ? ( @@ -266,7 +280,7 @@ function DNSProviderCreateModal({ values.meta[f.title], )} - {form.errors[name]} + {form.errors?.meta?.[fieldName]} )} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 74a06cda..23375f89 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3584,6 +3584,16 @@ ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.12.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"