mostly because code is being autogenerated by all the AI stuff using this prefix. it's also used in the stack trace.
93 lines
4.0 KiB
JavaScript
93 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
exports = module.exports = {
|
|
refreshDns,
|
|
sync
|
|
};
|
|
|
|
const apps = require('./apps.js'),
|
|
assert = require('node:assert'),
|
|
dashboard = require('./dashboard.js'),
|
|
debug = require('debug')('box:dyndns'),
|
|
dns = require('./dns.js'),
|
|
eventlog = require('./eventlog.js'),
|
|
fs = require('node:fs'),
|
|
mailServer = require('./mailserver.js'),
|
|
network = require('./network.js'),
|
|
paths = require('./paths.js'),
|
|
safe = require('safetydance'),
|
|
tasks = require('./tasks.js');
|
|
|
|
// FIXME: this races with apptask. can result in a conflict if apptask is doing some dns operation and this code changes entries
|
|
async function refreshDns(auditSource) {
|
|
assert.strictEqual(typeof auditSource, 'object');
|
|
|
|
const ipv4 = await network.getIPv4();
|
|
const ipv6 = await network.getIPv6();
|
|
|
|
const info = safe.JSON.parse(safe.fs.readFileSync(paths.DYNDNS_INFO_FILE, 'utf8')) || { ipv4: null, ipv6: null };
|
|
const ipv4Changed = info.ipv4 !== ipv4;
|
|
const ipv6Changed = ipv6 && info.ipv6 !== ipv6; // both should be RFC 5952 format
|
|
|
|
if (!ipv4Changed && !ipv6Changed) {
|
|
debug(`refreshDns: no change in IP. ipv4: ${ipv4} ipv6: ${ipv6}`);
|
|
return;
|
|
}
|
|
|
|
debug(`refreshDns: updating IP from ${info.ipv4} to ipv4: ${ipv4} (changed: ${ipv4Changed}) ipv6: ${ipv6} (changed: ${ipv6Changed})`);
|
|
|
|
const taskId = await tasks.add(tasks.TASK_SYNC_DYNDNS, [ ipv4Changed ? ipv4 : null, ipv6Changed ? ipv6 : null, auditSource ]);
|
|
// background
|
|
tasks.startTask(taskId, {})
|
|
.then(async () => {
|
|
await eventlog.add(eventlog.ACTION_DYNDNS_UPDATE, auditSource, { taskId, fromIpv4: info.ipv4, fromIpv6: info.ipv6, toIpv4: ipv4, toIpv6: ipv6 });
|
|
info.ipv4 = ipv4;
|
|
info.ipv6 = ipv6;
|
|
await fs.promises.writeFile(paths.DYNDNS_INFO_FILE, JSON.stringify(info), 'utf8');
|
|
})
|
|
.catch(async (error) => {
|
|
await eventlog.add(eventlog.ACTION_DYNDNS_UPDATE, auditSource, { taskId, fromIpv4: info.ipv4, fromIpv6: info.ipv6, toIpv4: ipv4, toIpv6: ipv6, errorMessage: error.message });
|
|
});
|
|
|
|
return taskId;
|
|
}
|
|
|
|
async function sync(ipv4, ipv6, auditSource, progressCallback) {
|
|
assert(ipv4 === null || typeof ipv4 === 'string');
|
|
assert(ipv6 === null || typeof ipv6 === 'string');
|
|
assert.strictEqual(typeof auditSource, 'object');
|
|
assert.strictEqual(typeof progressCallback, 'function');
|
|
|
|
let percent = 5;
|
|
const { domain:dashboardDomain, fqdn:dashboardFqdn, subdomain:dashboardSubdomain } = await dashboard.getLocation();
|
|
progressCallback({ percent, message: `Updating dashboard location ${dashboardFqdn}`});
|
|
if (ipv4) await safe(dns.upsertDnsRecords(dashboardSubdomain, dashboardDomain, 'A', [ ipv4 ]), { debug });
|
|
if (ipv6) await safe(dns.upsertDnsRecords(dashboardSubdomain, dashboardDomain, 'AAAA', [ ipv6 ]), { debug });
|
|
|
|
const { domain:mailDomain, fqdn:mailFqdn, subdomain:mailSubdomain } = await mailServer.getLocation();
|
|
percent += 10;
|
|
progressCallback({ percent, message: `Updating mail location ${mailFqdn}`});
|
|
if (dashboardFqdn !== mailFqdn) {
|
|
if (ipv4) await safe(dns.upsertDnsRecords(mailSubdomain, mailDomain, 'A', [ ipv4 ]), { debug });
|
|
if (ipv6) await safe(dns.upsertDnsRecords(mailSubdomain, mailDomain, 'AAAA', [ ipv6 ]), { debug });
|
|
}
|
|
|
|
const result = await apps.list();
|
|
for (const app of result) {
|
|
percent += Math.round(90/result.length);
|
|
progressCallback({ percent, message: `Updating app ${app.fqdn}`});
|
|
|
|
const locations = [{ domain: app.domain, subdomain: app.subdomain }]
|
|
.concat(app.secondaryDomains)
|
|
.concat(app.redirectDomains)
|
|
.concat(app.aliasDomains);
|
|
|
|
for (const location of locations) {
|
|
if (ipv4) await safe(dns.upsertDnsRecords(location.subdomain, location.domain, 'A', [ ipv4 ]), { debug });
|
|
if (ipv6) await safe(dns.upsertDnsRecords(location.subdomain, location.domain, 'AAAA', [ ipv6 ], { debug }));
|
|
}
|
|
}
|
|
|
|
progressCallback({ percent: 100, message: 'refreshDNS: updated apps' });
|
|
}
|