fix: Better DNS check to prevent errors
This commit is contained in:
@@ -1,11 +1,31 @@
|
||||
import { dev } from '$app/env';
|
||||
import { asyncExecShell, getDomain, getEngine, getUserDetails } from '$lib/common';
|
||||
import { checkDomainsIsValidInDNS, getDomain, getUserDetails, isDNSValid } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { ErrorHandler } from '$lib/database';
|
||||
import { t } from '$lib/translations';
|
||||
import { promises as dns } from 'dns';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { isIP } from 'is-ip';
|
||||
|
||||
export const get: RequestHandler = async (event) => {
|
||||
const { status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
const domain = event.url.searchParams.get('domain');
|
||||
if (!domain) {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
message: t.get('application.domain_required')
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
await isDNSValid(event, domain);
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorHandler(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { status, body } = await getUserDetails(event);
|
||||
@@ -14,11 +34,9 @@ export const post: RequestHandler = async (event) => {
|
||||
|
||||
let { fqdn, forceSave, dualCerts, isDNSCheckEnabled } = await event.request.json();
|
||||
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||
|
||||
try {
|
||||
const domain = getDomain(fqdn);
|
||||
const domainDualCert = domain.includes('www.') ? domain.replace('www.', '') : `www.${domain}`;
|
||||
const found = await db.isDomainConfigured({ id, fqdn });
|
||||
console.log(found);
|
||||
if (found) {
|
||||
throw {
|
||||
message: t.get('application.domain_already_in_use', {
|
||||
@@ -26,111 +44,9 @@ export const post: RequestHandler = async (event) => {
|
||||
})
|
||||
};
|
||||
}
|
||||
if (isDNSCheckEnabled) {
|
||||
if (!forceSave) {
|
||||
dns.setServers(['1.1.1.1', '8.8.8.8']);
|
||||
if (dualCerts) {
|
||||
try {
|
||||
const ipDomain = await dns.resolve4(domain);
|
||||
const ipDomainDualCert = await dns.resolve4(domainDualCert);
|
||||
console.log({ ipDomain, ipDomainDualCert });
|
||||
// TODO: Check if ipDomain and ipDomainDualCert are the same, but not like this
|
||||
if (
|
||||
ipDomain.length === ipDomainDualCert.length &&
|
||||
ipDomain.every((v) => ipDomainDualCert.indexOf(v) >= 0)
|
||||
) {
|
||||
let resolves = [];
|
||||
if (isIP(event.url.hostname)) {
|
||||
resolves = [event.url.hostname];
|
||||
} else {
|
||||
resolves = await dns.resolve4(event.url.hostname);
|
||||
}
|
||||
console.log({ resolves });
|
||||
for (const ip of ipDomain) {
|
||||
if (resolves.includes(ip)) {
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
}
|
||||
}
|
||||
for (const ip of ipDomainDualCert) {
|
||||
if (resolves.includes(ip)) {
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
}
|
||||
}
|
||||
throw false;
|
||||
} else {
|
||||
throw false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw {
|
||||
message: t.get('application.dns_not_set_error', { domain })
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let resolves = [];
|
||||
try {
|
||||
const ipDomain = await dns.resolve4(domain);
|
||||
console.log({ ipDomain });
|
||||
if (isIP(event.url.hostname)) {
|
||||
resolves = [event.url.hostname];
|
||||
} else {
|
||||
resolves = await dns.resolve4(event.url.hostname);
|
||||
}
|
||||
console.log({ resolves });
|
||||
for (const ip of ipDomain) {
|
||||
if (resolves.includes(ip)) {
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
}
|
||||
}
|
||||
throw false;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw {
|
||||
message: t.get('application.dns_not_set_error', { domain })
|
||||
};
|
||||
}
|
||||
}
|
||||
// let localReverseDomains = [];
|
||||
// let newIps = [];
|
||||
// let newIpsWWW = [];
|
||||
// let localIps = [];
|
||||
// try {
|
||||
// localReverseDomains = await dns.reverse(event.url.hostname)
|
||||
// } catch (error) { }
|
||||
// try {
|
||||
// localIps = await dns.resolve4(event.url.hostname);
|
||||
// } catch (error) { }
|
||||
// try {
|
||||
// newIps = await dns.resolve4(domain);
|
||||
// if (dualCerts) {
|
||||
// newIpsWWW = await dns.resolve4(`${isWWW ? nonWWW : domain}`)
|
||||
// }
|
||||
// console.log(newIps)
|
||||
// } catch (error) { }
|
||||
// console.log({ localIps, newIps, localReverseDomains, dualCerts, isWWW, nonWWW })
|
||||
// if (localReverseDomains?.length > 0) {
|
||||
// if ((newIps?.length === 0 || !newIps.includes(event.url.hostname)) || (dualCerts && newIpsWWW?.length === 0 && !newIpsWWW.includes(`${isWWW ? nonWWW : domain}`))) {
|
||||
// throw {
|
||||
// message: t.get('application.dns_not_set_error', { domain })
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// if (localIps?.length > 0) {
|
||||
// if (newIps?.length === 0 || !localIps.includes(newIps[0])) {
|
||||
// throw {
|
||||
// message: t.get('application.dns_not_set_error', { domain })
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if (isDNSCheckEnabled && !forceSave) {
|
||||
return await checkDomainsIsValidInDNS({ event, fqdn, dualCerts });
|
||||
}
|
||||
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
import Setting from '$lib/components/Setting.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { errorNotification } from '$lib/form';
|
||||
import { del, post } from '$lib/api';
|
||||
import { del, get, post } from '$lib/api';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import { browser } from '$app/env';
|
||||
import { getDomain } from '$lib/components/common';
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
let forceSave = false;
|
||||
let fqdn = settings.fqdn;
|
||||
let nonWWWDomain = fqdn && getDomain(fqdn).replace(/^www\./, '');
|
||||
let isFqdnSet = !!settings.fqdn;
|
||||
let loading = {
|
||||
save: false,
|
||||
@@ -96,6 +97,7 @@
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
loading.save = true;
|
||||
nonWWWDomain = fqdn && getDomain(fqdn).replace(/^www\./, '');
|
||||
if (fqdn !== settings.fqdn) {
|
||||
await post(`/settings/check.json`, { fqdn, forceSave, dualCerts, isDNSCheckEnabled });
|
||||
await post(`/settings.json`, { fqdn });
|
||||
@@ -106,6 +108,7 @@
|
||||
settings.minPort = minPort;
|
||||
settings.maxPort = maxPort;
|
||||
}
|
||||
forceSave = false;
|
||||
} catch ({ error }) {
|
||||
if (error?.startsWith($t('application.dns_not_set_partial_error'))) {
|
||||
forceSave = true;
|
||||
@@ -123,6 +126,14 @@
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
async function isDNSValid(domain) {
|
||||
try {
|
||||
await get(`/settings/check.json?domain=${domain}`);
|
||||
toast.push('Domain is valid in DNS.');
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@@ -176,6 +187,23 @@
|
||||
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
|
||||
placeholder="{$t('forms.eg')}: https://coolify.io"
|
||||
/>
|
||||
|
||||
{#if forceSave}
|
||||
<div class="pt-4">
|
||||
<button
|
||||
class="bg-coollabs hover:bg-coollabs-100"
|
||||
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain))}
|
||||
>Check {nonWWWDomain} DNS Record</button
|
||||
>
|
||||
{#if dualCerts}
|
||||
<button
|
||||
class="bg-coollabs hover:bg-coollabs-100"
|
||||
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`))}
|
||||
>Check www.{nonWWWDomain} DNS Record</button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-start py-6">
|
||||
|
||||
Reference in New Issue
Block a user