From f56d4dbbb3a001c4ad753c947473e2c157b80f3f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 5 May 2022 15:18:13 +0200 Subject: [PATCH] fix: Check domain for coolify before saving --- package.json | 1 + pnpm-lock.yaml | 103 +++++++++++---------------- src/routes/settings/check.json.ts | 113 ++++++++++++++++++++++++++++-- src/routes/settings/index.json.ts | 4 +- src/routes/settings/index.svelte | 19 +++-- 5 files changed, 167 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 29b7566ef..5c93290e9 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "generate-password": "1.7.0", "get-port": "6.1.2", "got": "12.0.3", + "is-ip": "^4.0.0", "js-cookie": "3.0.1", "js-yaml": "4.1.0", "jsonwebtoken": "8.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 46dca967e..10f21d2f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@iarna/toml': 2.2.5 @@ -31,6 +31,7 @@ specifiers: get-port: 6.1.2 got: 12.0.3 husky: 7.0.4 + is-ip: ^4.0.0 js-cookie: 3.0.1 js-yaml: 4.1.0 jsonwebtoken: 8.5.1 @@ -71,6 +72,7 @@ dependencies: generate-password: 1.7.0 get-port: 6.1.2 got: 12.0.3 + is-ip: 4.0.0 js-cookie: 3.0.1 js-yaml: 4.1.0 jsonwebtoken: 8.5.1 @@ -88,29 +90,29 @@ devDependencies: '@types/js-yaml': 4.0.5 '@types/node': 17.0.25 '@types/node-forge': 1.0.1 - '@typescript-eslint/eslint-plugin': 4.31.1_8ede7edd7694646e12d33c52460f622c - '@typescript-eslint/parser': 4.31.1_eslint@7.32.0+typescript@4.6.3 + '@typescript-eslint/eslint-plugin': 4.31.1_r3ph5xlwsrsg4ewthrjemd3cfq + '@typescript-eslint/parser': 4.31.1_hrkuebk64jiu2ut2d2sm4oylnu '@zerodevx/svelte-toast': 0.7.1 autoprefixer: 10.4.4_postcss@8.4.12 cross-env: 7.0.3 cross-var: 1.1.0 eslint: 7.32.0 eslint-config-prettier: 8.5.0_eslint@7.32.0 - eslint-plugin-svelte3: 3.4.1_eslint@7.32.0+svelte@3.47.0 + eslint-plugin-svelte3: 3.4.1_4oxeyilw5mxcaksmcxtpjddhfe husky: 7.0.4 lint-staged: 12.4.0 postcss: 8.4.12 prettier: 2.6.2 - prettier-plugin-svelte: 2.7.0_prettier@2.6.2+svelte@3.47.0 + prettier-plugin-svelte: 2.7.0_sqtt6dzjlskmywoml5ykunxlce prettier-plugin-tailwindcss: 0.1.10_prettier@2.6.2 prisma: 3.11.1 svelte: 3.47.0 - svelte-check: 2.7.0_postcss@8.4.12+svelte@3.47.0 - svelte-preprocess: 4.10.6_41810887ae6c6d59323116f47e33fa38 + svelte-check: 2.7.0_cp6olp7pwsfaq5mjijwt65d6uy + svelte-preprocess: 4.10.6_igaqrb5onrwvsmrrc32h4m72ha svelte-select: 4.4.7 sveltekit-i18n: 2.1.2_svelte@3.47.0 tailwindcss: 3.0.24_ts-node@10.7.0 - ts-node: 10.7.0_de7c86b0cde507c63a0402da5b982bd3 + ts-node: 10.7.0_3z6inmgn4ud4moqealnfxgbl2m tslib: 2.3.1 typescript: 4.6.3 @@ -494,26 +496,6 @@ packages: '@types/responselike': 1.0.0 dev: false - /@types/docker-modem/3.0.2: - resolution: - { - integrity: sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ== - } - dependencies: - '@types/node': 17.0.23 - '@types/ssh2': 0.5.52 - dev: true - - /@types/dockerode/3.3.8: - resolution: - { - integrity: sha512-/Hip29GzPBWfbSS87lyQDVoB7Ja+kr8oOFWXsySxNFa7jlyj3Yws8LaZRmn1xZl7uJH3Xxsg0oI09GHpT1pIBw== - } - dependencies: - '@types/docker-modem': 3.0.2 - '@types/node': 17.0.23 - dev: true - /@types/http-cache-semantics/4.0.1: resolution: { @@ -591,26 +573,7 @@ packages: '@types/node': 17.0.25 dev: true - /@types/ssh2-streams/0.1.9: - resolution: - { - integrity: sha512-I2J9jKqfmvXLR5GomDiCoHrEJ58hAOmFrekfFqmCFd+A6gaEStvWnPykoWUwld1PNg4G5ag1LwdA+Lz1doRJqg== - } - dependencies: - '@types/node': 17.0.23 - dev: true - - /@types/ssh2/0.5.52: - resolution: - { - integrity: sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg== - } - dependencies: - '@types/node': 17.0.23 - '@types/ssh2-streams': 0.1.9 - dev: true - - /@typescript-eslint/eslint-plugin/4.31.1_8ede7edd7694646e12d33c52460f622c: + /@typescript-eslint/eslint-plugin/4.31.1_r3ph5xlwsrsg4ewthrjemd3cfq: resolution: { integrity: sha512-UDqhWmd5i0TvPLmbK5xY3UZB0zEGseF+DHPghZ37Sb83Qd3p8ujhvAtkU4OF46Ka5Pm5kWvFIx0cCTBFKo0alA== @@ -624,8 +587,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.31.1_eslint@7.32.0+typescript@4.6.3 - '@typescript-eslint/parser': 4.31.1_eslint@7.32.0+typescript@4.6.3 + '@typescript-eslint/experimental-utils': 4.31.1_hrkuebk64jiu2ut2d2sm4oylnu + '@typescript-eslint/parser': 4.31.1_hrkuebk64jiu2ut2d2sm4oylnu '@typescript-eslint/scope-manager': 4.31.1 debug: 4.3.3 eslint: 7.32.0 @@ -638,7 +601,7 @@ packages: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.31.1_eslint@7.32.0+typescript@4.6.3: + /@typescript-eslint/experimental-utils/4.31.1_hrkuebk64jiu2ut2d2sm4oylnu: resolution: { integrity: sha512-NtoPsqmcSsWty0mcL5nTZXMf7Ei0Xr2MT8jWjXMVgRK0/1qeQ2jZzLFUh4QtyJ4+/lPUyMw5cSfeeME+Zrtp9Q== @@ -659,7 +622,7 @@ packages: - typescript dev: true - /@typescript-eslint/parser/4.31.1_eslint@7.32.0+typescript@4.6.3: + /@typescript-eslint/parser/4.31.1_hrkuebk64jiu2ut2d2sm4oylnu: resolution: { integrity: sha512-dnVZDB6FhpIby6yVbHkwTKkn2ypjVIfAR9nh+kYsA/ZL0JlTsd22BiDjouotisY3Irmd3OW1qlk9EI5R8GrvRQ== @@ -2652,7 +2615,7 @@ packages: eslint: 7.32.0 dev: true - /eslint-plugin-svelte3/3.4.1_eslint@7.32.0+svelte@3.47.0: + /eslint-plugin-svelte3/3.4.1_4oxeyilw5mxcaksmcxtpjddhfe: resolution: { integrity: sha512-7p59WG8qV8L6wLdl4d/c3mdjkgVglQCdv5XOTk/iNPBKXuuV+Q0eFP5Wa6iJd/G2M1qR3BkLPEzaANOqKAZczw== @@ -3322,6 +3285,14 @@ packages: - supports-color dev: false + /ip-regex/5.0.0: + resolution: + { + integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw== + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + dev: false + /is-binary-path/2.1.0: resolution: { @@ -3380,6 +3351,16 @@ packages: is-extglob: 2.1.1 dev: true + /is-ip/4.0.0: + resolution: + { + integrity: sha512-4B4XA2HEIm/PY+OSpeMBXr8pGWBYbXuHgjMAqrwbLO3CPTCAd9ArEJzBUKGZtk9viY6+aSfadGnWyjY3ydYZkw== + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + dependencies: + ip-regex: 5.0.0 + dev: false + /is-number/7.0.0: resolution: { @@ -4142,7 +4123,7 @@ packages: postcss: 8.4.12 dev: true - /postcss-load-config/3.1.4_postcss@8.4.12+ts-node@10.7.0: + /postcss-load-config/3.1.4_ysmyu6g5dtd6yanj6zrab4uqoy: resolution: { integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== @@ -4159,7 +4140,7 @@ packages: dependencies: lilconfig: 2.0.5 postcss: 8.4.12 - ts-node: 10.7.0_de7c86b0cde507c63a0402da5b982bd3 + ts-node: 10.7.0_3z6inmgn4ud4moqealnfxgbl2m yaml: 1.10.2 dev: true @@ -4214,7 +4195,7 @@ packages: engines: { node: '>= 0.8.0' } dev: true - /prettier-plugin-svelte/2.7.0_prettier@2.6.2+svelte@3.47.0: + /prettier-plugin-svelte/2.7.0_sqtt6dzjlskmywoml5ykunxlce: resolution: { integrity: sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA== @@ -4897,7 +4878,7 @@ packages: engines: { node: '>= 0.4' } dev: true - /svelte-check/2.7.0_postcss@8.4.12+svelte@3.47.0: + /svelte-check/2.7.0_cp6olp7pwsfaq5mjijwt65d6uy: resolution: { integrity: sha512-GrvG24j0+i8AOm0k0KyJ6Dqc+TAR2yzB7rtS4nljHStunVxCTr/1KYlv4EsOeoqtHLzeWMOd5D2O6nDdP/yw4A== @@ -4913,7 +4894,7 @@ packages: sade: 1.7.4 source-map: 0.7.3 svelte: 3.47.0 - svelte-preprocess: 4.10.6_41810887ae6c6d59323116f47e33fa38 + svelte-preprocess: 4.10.6_igaqrb5onrwvsmrrc32h4m72ha typescript: 4.6.3 transitivePeerDependencies: - '@babel/core' @@ -4946,7 +4927,7 @@ packages: } dev: false - /svelte-preprocess/4.10.6_41810887ae6c6d59323116f47e33fa38: + /svelte-preprocess/4.10.6_igaqrb5onrwvsmrrc32h4m72ha: resolution: { integrity: sha512-I2SV1w/AveMvgIQlUF/ZOO3PYVnhxfcpNyGt8pxpUVhPfyfL/CZBkkw/KPfuFix5FJ9TnnNYMhACK3DtSaYVVQ== @@ -5078,7 +5059,7 @@ packages: picocolors: 1.0.0 postcss: 8.4.12 postcss-js: 4.0.0_postcss@8.4.12 - postcss-load-config: 3.1.4_postcss@8.4.12+ts-node@10.7.0 + postcss-load-config: 3.1.4_ysmyu6g5dtd6yanj6zrab4uqoy postcss-nested: 5.0.6_postcss@8.4.12 postcss-selector-parser: 6.0.10 postcss-value-parser: 4.2.0 @@ -5152,7 +5133,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /ts-node/10.7.0_de7c86b0cde507c63a0402da5b982bd3: + /ts-node/10.7.0_3z6inmgn4ud4moqealnfxgbl2m: resolution: { integrity: sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== diff --git a/src/routes/settings/check.json.ts b/src/routes/settings/check.json.ts index bec577001..66cbe7dbf 100644 --- a/src/routes/settings/check.json.ts +++ b/src/routes/settings/check.json.ts @@ -1,25 +1,124 @@ -import { asyncExecShell, getEngine, getUserDetails } from '$lib/common'; +import { dev } from '$app/env'; +import { asyncExecShell, getDomain, getEngine, getUserDetails } 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 post: RequestHandler = async (event) => { const { status, body } = await getUserDetails(event); if (status === 401) return { status, body }; const { id } = event.params; - let { fqdn } = await event.request.json(); + 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 }); - return { - status: found ? 500 : 200, - body: { - error: - found && t.get('application.domain_already_in_use', { domain: fqdn.replace('www.', '') }) + if (found) { + throw { + message: t.get('application.domain_already_in_use', { + domain: getDomain(fqdn).replace('www.', '') + }) + }; + } + 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 }); + 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 }); + if (resolves.includes(ipDomain) || resolves.includes(ipDomainDualCert)) { + console.log('OK'); + } else { + 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 }); + if (resolves.includes(ipDomain)) { + console.log('OK'); + } else { + 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 }) + // }; + // } + // } } + } + + return { + status: 200 }; } catch (error) { return ErrorHandler(error); diff --git a/src/routes/settings/index.json.ts b/src/routes/settings/index.json.ts index 5546d782f..21f4907f2 100644 --- a/src/routes/settings/index.json.ts +++ b/src/routes/settings/index.json.ts @@ -1,3 +1,4 @@ +import { dev } from '$app/env'; import { getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { listSettings, ErrorHandler } from '$lib/database'; @@ -71,7 +72,8 @@ export const post: RequestHandler = async (event) => { minPort, maxPort, isAutoUpdateEnabled, - isDNSCheckEnabled + isDNSCheckEnabled, + forceSave } = await event.request.json(); try { const { id } = await db.listSettings(); diff --git a/src/routes/settings/index.svelte b/src/routes/settings/index.svelte index 20e1c788d..1a4f25801 100644 --- a/src/routes/settings/index.svelte +++ b/src/routes/settings/index.svelte @@ -47,6 +47,7 @@ let minPort = settings.minPort; let maxPort = settings.maxPort; + let forceSave = false; let fqdn = settings.fqdn; let isFqdnSet = !!settings.fqdn; let loading = { @@ -96,7 +97,7 @@ try { loading.save = true; if (fqdn !== settings.fqdn) { - await post(`/settings/check.json`, { fqdn }); + await post(`/settings/check.json`, { fqdn, forceSave, dualCerts, isDNSCheckEnabled }); await post(`/settings.json`, { fqdn }); return window.location.reload(); } @@ -106,6 +107,9 @@ settings.maxPort = maxPort; } } catch ({ error }) { + if (error?.startsWith($t('application.dns_not_set_partial_error'))) { + forceSave = true; + } return errorNotification(error); } finally { loading.save = false; @@ -131,11 +135,18 @@
{$t('index.global_settings')}
{loading.save + ? $t('forms.saving') + : forceSave + ? $t('forms.confirm_continue') + : $t('forms.save')} + {#if isFqdnSet}