Skip to content

Commit e890bfc

Browse files
committed
Certificates table compliance and other stuff
1 parent 9a5cbbb commit e890bfc

File tree

16 files changed

+666
-109
lines changed

16 files changed

+666
-109
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Access Lists Help
2+
3+
todo
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Certificates Help
2+
3+
todo
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Nginx Templates Help
2+
3+
todo
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
export * as AccessLists from "./AccessLists.md";
2+
export * as Certificates from "./Certificates.md";
13
export * as CertificateAuthorities from "./CertificateAuthorities.md";
24
export * as DNSProviders from "./DNSProviders.md";
5+
export * as NginxTemplates from "./NginxTemplates.md";

frontend/src/locale/src/en.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@
311311
"capability.users.manage": {
312312
"defaultMessage": "Manage Users"
313313
},
314+
"certificate.create": {
315+
"defaultMessage": "Create Certificate"
316+
},
314317
"certificate-authorities.title": {
315318
"defaultMessage": "Certificate Authorities"
316319
},
@@ -380,9 +383,6 @@
380383
"create-access-list-title": {
381384
"defaultMessage": "There are no Access Lists"
382385
},
383-
"create-certificate": {
384-
"defaultMessage": "Create Certificate"
385-
},
386386
"create-certificate-title": {
387387
"defaultMessage": "There are no Certificates"
388388
},
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import {
2+
Button,
3+
Checkbox,
4+
FormControl,
5+
FormErrorMessage,
6+
FormLabel,
7+
Input,
8+
Modal,
9+
ModalOverlay,
10+
ModalContent,
11+
ModalHeader,
12+
ModalCloseButton,
13+
ModalBody,
14+
ModalFooter,
15+
Stack,
16+
useToast,
17+
} from "@chakra-ui/react";
18+
import { CertificateAuthority } from "api/npm";
19+
import { PrettyButton } from "components";
20+
import { Formik, Form, Field } from "formik";
21+
import { useSetCertificateAuthority } from "hooks";
22+
import { intl } from "locale";
23+
import { validateNumber, validateString } from "modules/Validations";
24+
25+
interface CertificateCreateModalProps {
26+
isOpen: boolean;
27+
onClose: () => void;
28+
}
29+
function CertificateCreateModal({
30+
isOpen,
31+
onClose,
32+
}: CertificateCreateModalProps) {
33+
const toast = useToast();
34+
const { mutate: setCertificateAuthority } = useSetCertificateAuthority();
35+
36+
const onSubmit = async (
37+
payload: CertificateAuthority,
38+
{ setErrors, setSubmitting }: any,
39+
) => {
40+
const showErr = (msg: string) => {
41+
toast({
42+
description: intl.formatMessage({
43+
id: `error.${msg}`,
44+
}),
45+
status: "error",
46+
position: "top",
47+
duration: 3000,
48+
isClosable: true,
49+
});
50+
};
51+
52+
setCertificateAuthority(payload, {
53+
onError: (err: any) => {
54+
if (err.message === "ca-bundle-does-not-exist") {
55+
setErrors({
56+
caBundle: intl.formatMessage({
57+
id: `error.${err.message}`,
58+
}),
59+
});
60+
} else {
61+
showErr(err.message);
62+
}
63+
},
64+
onSuccess: () => onClose(),
65+
onSettled: () => setSubmitting(false),
66+
});
67+
};
68+
69+
return (
70+
<Modal isOpen={isOpen} onClose={onClose} closeOnOverlayClick={false}>
71+
<ModalOverlay />
72+
<ModalContent>
73+
<Formik
74+
initialValues={
75+
{
76+
name: "",
77+
acmeshServer: "",
78+
caBundle: "",
79+
maxDomains: 5,
80+
isWildcardSupported: false,
81+
} as CertificateAuthority
82+
}
83+
onSubmit={onSubmit}>
84+
{({ isSubmitting }) => (
85+
<Form>
86+
<ModalHeader>
87+
{intl.formatMessage({ id: "certificate-authority.create" })}
88+
</ModalHeader>
89+
<ModalCloseButton />
90+
<ModalBody>
91+
<Stack spacing={4}>
92+
<Field name="name" validate={validateString(1, 100)}>
93+
{({ field, form }: any) => (
94+
<FormControl
95+
isRequired
96+
isInvalid={form.errors.name && form.touched.name}>
97+
<FormLabel htmlFor="name">
98+
{intl.formatMessage({
99+
id: "certificate-authority.name",
100+
})}
101+
</FormLabel>
102+
<Input
103+
{...field}
104+
id="name"
105+
placeholder={intl.formatMessage({
106+
id: "certificate-authority.name",
107+
})}
108+
/>
109+
<FormErrorMessage>{form.errors.name}</FormErrorMessage>
110+
</FormControl>
111+
)}
112+
</Field>
113+
<Field name="acmeshServer" validate={validateString(2, 255)}>
114+
{({ field, form }: any) => (
115+
<FormControl
116+
isRequired
117+
isInvalid={
118+
form.errors.acmeshServer && form.touched.acmeshServer
119+
}>
120+
<FormLabel htmlFor="acmeshServer">
121+
{intl.formatMessage({
122+
id: "certificate-authority.acmesh-server",
123+
})}
124+
</FormLabel>
125+
<Input
126+
{...field}
127+
id="acmeshServer"
128+
placeholder="https://example.com/acme/directory"
129+
/>
130+
<FormErrorMessage>
131+
{form.errors.acmeshServer}
132+
</FormErrorMessage>
133+
</FormControl>
134+
)}
135+
</Field>
136+
<Field name="caBundle" validate={validateString(2, 255)}>
137+
{({ field, form }: any) => (
138+
<FormControl
139+
isRequired
140+
isInvalid={
141+
form.errors.caBundle && form.touched.caBundle
142+
}>
143+
<FormLabel htmlFor="caBundle">
144+
{intl.formatMessage({
145+
id: "certificate-authority.ca-bundle",
146+
})}
147+
</FormLabel>
148+
<Input
149+
{...field}
150+
id="caBundle"
151+
placeholder="/path/to/certs/custom-ca-bundle.crt"
152+
/>
153+
<FormErrorMessage>
154+
{form.errors.caBundle}
155+
</FormErrorMessage>
156+
</FormControl>
157+
)}
158+
</Field>
159+
<Field
160+
name="maxDomains"
161+
validate={validateNumber(1)}
162+
type="number">
163+
{({ field, form }: any) => (
164+
<FormControl
165+
isRequired
166+
isInvalid={
167+
form.errors.maxDomains && form.touched.maxDomains
168+
}>
169+
<FormLabel htmlFor="maxDomains">
170+
{intl.formatMessage({
171+
id: "certificate-authority.max-domains",
172+
})}
173+
</FormLabel>
174+
<Input {...field} id="maxDomains" type="number" />
175+
<FormErrorMessage>
176+
{form.errors.maxDomains}
177+
</FormErrorMessage>
178+
</FormControl>
179+
)}
180+
</Field>
181+
<Field name="isWildcardSupported" type="checkbox">
182+
{({ field, form }: any) => (
183+
<FormControl
184+
isInvalid={
185+
form.errors.isWildcardSupported &&
186+
form.touched.isWildcardSupported
187+
}>
188+
<Checkbox
189+
{...field}
190+
isChecked={field.checked}
191+
size="md"
192+
colorScheme="green">
193+
{intl.formatMessage({
194+
id: "certificate-authority.has-wildcard-support",
195+
})}
196+
</Checkbox>
197+
<FormErrorMessage>
198+
{form.errors.isWildcardSupported}
199+
</FormErrorMessage>
200+
</FormControl>
201+
)}
202+
</Field>
203+
</Stack>
204+
</ModalBody>
205+
<ModalFooter>
206+
<PrettyButton mr={3} isLoading={isSubmitting}>
207+
{intl.formatMessage({ id: "form.save" })}
208+
</PrettyButton>
209+
<Button onClick={onClose} isLoading={isSubmitting}>
210+
{intl.formatMessage({ id: "form.cancel" })}
211+
</Button>
212+
</ModalFooter>
213+
</Form>
214+
)}
215+
</Formik>
216+
</ModalContent>
217+
</Modal>
218+
);
219+
}
220+
221+
export { CertificateCreateModal };

0 commit comments

Comments
 (0)