admin/internet: support multiple ddns URLs
Massimo Melina committed
May 2, 2024 at 23:45 UTC
2599d874309f6231deb4c4beea6942b0dcb3bcff
3 files changed
+21
-16
admin/src/InternetPage.ts
+2
-2
@@ -66,7 +66,7 @@ export default function InternetPage() {
66
data && h(Flex, {},
67
data.error ? h(ErrorIcon, { color: 'error', ref }) : h(Check, { color: 'success', ref }),
68
formatTimestamp(data.ts), ' – ',
69
- prefix("Error: ", stripTags(data.error)) || "Updated successfully",
69
+ prefix("Error: ", stripTags(data.error)).slice(0, 500) || "Updated successfully",
70
),
71
"This tool can keep your domain updated with your latest IP address. Not every service is compatible, and most of them have their own software for the job, which is superior, but we offer this lightweight solution in case you are more keen to it.",
72
h(ConfigForm<{
@@ -99,7 +99,7 @@ export default function InternetPage() {
99
}, label + " wizard")
100
)
101
),
102
- { k: CFG.dynamic_dns_url, label: "Updater URL",
102
+ { k: CFG.dynamic_dns_url, label: "Updater URL", multiline: true,
103
helperText: "Refer to your DNS service provider to know what URL can automatically keep your domain updated. Supported symbols are $IP4, $IP6, $IPX. Optionally, you can append “>” followed by a regular expression to determine a successful answer, otherwise status code will be used."
104
},
105
]
config.md
+3
-1
@@ -106,7 +106,9 @@ Configuration can be done in several ways
106
- `geo_allow` set true if `geo_list` should be treated as white-list, set false for black-list. Default will ignore the list.
107
- `geo_list` list of country codes to be used as white-list or black-list. Default is empty.
108
- `geo_allow_unknown` set false to disconnect connections for which country cannot be determined. Works only if `geo_allow` is set. Default is true.
109
-- `dynamic_dns_url` URL to be requested to keep a domain updated with your latest IP address. Optionally, you can append “>” followed by a regular expression to determine a successful answer, otherwise status code will be used.
109
+- `dynamic_dns_url` URL to be requested to keep a domain updated with your latest IP address.
110
+ Optionally, you can append “>” followed by a regular expression to determine a successful answer, otherwise status code will be used.
111
+ Multiple URLs are supported and you can specify one for each line.
112
- `create-admin` special entry to quickly create an admin account. The value will be set as password. As soon as the account is created, this entry is removed.
113
114
#### Virtual File System (VFS)
src/ddns.ts
+16
-13
@@ -19,24 +19,27 @@ dynamicDnsUrl.sub(v => {
19
stop?.()
20
if (!v) return
21
let lastIps: any
22
- const [templateUrl, re] = splitAt('>', v)
22
stop = repeat(HOUR, async () => {
23
const ips = await getPublicIps()
24
if (_.isEqual(lastIps, ips)) return
25
lastIps = ips
27
- const url = replace(templateUrl, {
28
- IPX: ips[0] || '',
29
- IP4: _.find(ips, isIPv4) || '',
30
- IP6: _.find(ips, isIPv6) || '',
31
- }, '$')
32
- const error = await httpWithBody(url, { httpThrow: false, headers: { 'User-Agent': "HFS/" + VERSION } }) // UA specified as requested by no-ip guidelines
33
- .then(async res => {
34
- const str = String(res.body).trim()
35
- return (re ? str.match(re) : res.ok) ? '' : (str || res.statusMessage)
36
- }, (err: any) => err.code || err.message || String(err) )
37
- last = { ts: new Date().toJSON(), error, url }
26
+ const all = await Promise.all(v.split('\n').map(async line => {
27
+ const [templateUrl, re] = splitAt('>', line)
28
+ const url = replace(templateUrl, {
29
+ IPX: ips[0] || '',
30
+ IP4: _.find(ips, isIPv4) || '',
31
+ IP6: _.find(ips, isIPv6) || '',
32
+ }, '$')
33
+ const error = await httpWithBody(url, { httpThrow: false, headers: { 'User-Agent': "HFS/" + VERSION } }) // UA specified as requested by no-ip guidelines
34
+ .then(async res => {
35
+ const str = String(res.body).trim()
36
+ return (re ? str.match(re) : res.ok) ? '' : (str || res.statusMessage)
37
+ }, (err: any) => err.code || err.message || String(err) )
38
+ return { ts: new Date().toJSON(), error, url }
39
+ }))
40
+ last = _.find(all, 'error') || all[0] // the system is designed for just one result, and we give precedence to errors
41
events.emit('dynamicDnsError', last)
39
- console.log('dynamic dns update', error || 'ok')
42
+ console.log('dynamic dns update', last?.error || 'ok')
43
})
44
})
45