admin/internet: "automatic renew" option

Massimo Melina committed Sep 22, 2023 at 15:53 UTC a93cc934538162b23385664044868c6c5020f502
1 file changed +10 -9
admin/src/InternetPage.ts
+10 -9
@@ -5,7 +5,7 @@ import { apiCall, useApiEx } from './api'
5 import { closeDialog, DAY, formatTimestamp, with_ } from '@hfs/shared'
6 import { Flex, LinkBtn, manipulateConfig, isIP, Btn } from './misc'
7 import { alertDialog, confirmDialog, promptDialog, toast } from './dialog'
8 -import { Form, NumberField } from '@hfs/mui-grid-form'
8 +import { BoolField, Form, NumberField } from '@hfs/mui-grid-form'
9 import md from './md'
10 import { isCertError } from './OptionsPage'
11 import { changeBaseUrl } from './FileForm'
@@ -40,10 +40,11 @@ export default function InternetPage() {
40
41 function httpsBox() {
42 const { error, listening } = status.data?.https ||{}
43 - const [acme, setAcme] = useState<any>()
43 + const [values, setValues] = useState<any>()
44 const cert = useApiEx('get_cert')
45 - useEffect(() => { apiCall('get_config', { only: ['acme_domain', 'acme_email'] }).then(setAcme) } , [])
46 - if (!status || !acme) return h(CircularProgress)
45 + useEffect(() => { apiCall('get_config', { only: ['acme_domain', 'acme_email', 'acme_renew'] }).then(setValues) } , [])
46 + useApiEx('set_config', { values })
47 + if (!status || !values) return h(CircularProgress)
48 return element || status.element || h(Card, {}, h(CardContent, {},
49 h(Flex, { gap: '.5em', fontSize: 'x-large', mb: 1, alignItems: 'center' }, "HTTPS",
50 h(Lock, { color: listening && !error ? 'success' : 'warning' }) ),
@@ -59,26 +60,26 @@ export default function InternetPage() {
60 h(Form, {
61 gap: 1,
62 gridProps: {rowSpacing:1},
62 - values: acme,
63 + values,
64 set(v, k) {
64 - setAcme((was: any) => ({ ...was, [k]: v }))
65 + setValues((was: any) => ({ ...was, [k]: v }))
66 },
67 fields: [
68 md("Generate certificate using [Let's Encrypt](https://letsencrypt.org)"),
69 { k: 'acme_domain', label: "Certificate domain", sm: 6, required: true },
70 { k: 'acme_email', label: "Certificate e-mail", sm: 6 },
71 + { k: 'acme_renew', label: "Automatic renew one month before expiration", comp: BoolField, disabled: !values.acme_domain },
72 ],
73 save: {
74 children: "Request",
75 startIcon: h(Send),
76 async onClick() {
75 - const domain = acme.acme_domain
77 + const domain = values.acme_domain
78 const fresh = domain === cert.data.subject?.CN && Number(new Date(cert.data.validTo)) - Date.now() >= 30 * DAY
79 if (fresh && !await confirmDialog("Your certificate is still good", { confirmText: "Make a new one anyway" }))
80 return
79 - await apiCall('set_config', { values: acme })
81 if (!await confirmDialog("HFS must temporarily serve HTTP on public port 80, and your router must be configured or this operation will fail")) return
81 - await apiCall('make_cert', { domain, email: acme.acme_email }, { timeout: 20_000 })
82 + await apiCall('make_cert', { domain, email: values.acme_email }, { timeout: 20_000 })
83 .then(async () => {
84 await alertDialog("Certificate created", 'success')
85 await manipulateConfig('https_port', async v => {