diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 9d0373071..32ada0494 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -26,7 +26,7 @@ "marked": "^15.0.12", "moment": "^2.30.1", "moment-timezone": "^0.6.0", - "pankow": "^3.1.1", + "pankow": "^3.1.2", "sass": "^1.89.2", "vite": "^6.3.5", "vue": "^3.5.16", @@ -2370,9 +2370,9 @@ } }, "node_modules/pankow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pankow/-/pankow-3.1.1.tgz", - "integrity": "sha512-nAVCrHR1WopgeEnVVMShBV2Xuo1BC2szwrAX1EjGF2DLnqxTl1+gCg01NmixPN6270Vst6uqRDmke/TAJnlLag==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pankow/-/pankow-3.1.2.tgz", + "integrity": "sha512-6DpIWDifgR4c3Rvs+X+V+XEdWBs8HUFFUo1K8LOWxsHwd7tbaUlBmPRM9aSrYiffWASpN1gj2Axsi/yBl50VXw==", "license": "ISC", "dependencies": { "@fontsource/inter": "^5.2.6", @@ -4242,9 +4242,9 @@ } }, "pankow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pankow/-/pankow-3.1.1.tgz", - "integrity": "sha512-nAVCrHR1WopgeEnVVMShBV2Xuo1BC2szwrAX1EjGF2DLnqxTl1+gCg01NmixPN6270Vst6uqRDmke/TAJnlLag==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pankow/-/pankow-3.1.2.tgz", + "integrity": "sha512-6DpIWDifgR4c3Rvs+X+V+XEdWBs8HUFFUo1K8LOWxsHwd7tbaUlBmPRM9aSrYiffWASpN1gj2Axsi/yBl50VXw==", "requires": { "@fontsource/inter": "^5.2.6", "@fortawesome/fontawesome-free": "^6.7.2", diff --git a/dashboard/package.json b/dashboard/package.json index a815ec701..52780ebea 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -27,7 +27,7 @@ "marked": "^15.0.12", "moment": "^2.30.1", "moment-timezone": "^0.6.0", - "pankow": "^3.1.1", + "pankow": "^3.1.2", "sass": "^1.89.2", "vite": "^6.3.5", "vue": "^3.5.16", diff --git a/dashboard/src/components/AppInstallDialog.vue b/dashboard/src/components/AppInstallDialog.vue index a0b679abe..00cd494c0 100644 --- a/dashboard/src/components/AppInstallDialog.vue +++ b/dashboard/src/components/AppInstallDialog.vue @@ -3,7 +3,7 @@ import { ref, computed, useTemplateRef, onMounted, inject } from 'vue'; import { marked } from 'marked'; import { Button, Dialog, SingleSelect, FormGroup, TextInput, InputGroup } from 'pankow'; -import { prettyDate, prettyBinarySize } from 'pankow/utils'; +import { prettyDate, prettyBinarySize, isValidDomain } from 'pankow/utils'; import AccessControl from './AccessControl.vue'; import PortBindings from './PortBindings.vue'; import DomainsModel from '../models/DomainsModel.js'; @@ -36,12 +36,7 @@ const domains = ref([]); const formValid = computed(() => { if (!domain.value) return false; - if (location.value) { - // label validation - if (location.value.split('.').some(function (p) { return p.length > 63 || p.length < 1; })) return false; - if (location.value.match(/^[A-Za-z0-9-.]+$/) === null) return false; - if (/^[-.]/.test(location.value)) return false; - } + if (location.value && !isValidDomain(location.value + '.' + domain.value)) return false; if (accessRestrictionOption.value === ACL_OPTIONS.RESTRICTED && (accessRestrictionAcl.value.users.length === 0 && accessRestrictionAcl.value.groups.length === 0)) return false; diff --git a/dashboard/src/components/app/Location.vue b/dashboard/src/components/app/Location.vue index d9e96b487..8dcf988e6 100644 --- a/dashboard/src/components/app/Location.vue +++ b/dashboard/src/components/app/Location.vue @@ -2,6 +2,7 @@ import { ref, onMounted, computed } from 'vue'; import { Button, SingleSelect, InputGroup, FormGroup, TextInput } from 'pankow'; +import { isValidDomain } from 'pankow/utils'; import PortBindings from '../PortBindings.vue'; import AppsModel from '../../models/AppsModel.js'; import DomainsModel from '../../models/DomainsModel.js'; @@ -52,6 +53,23 @@ function onAddRedirect() { }); } +const formValid = computed(() => { + if (!domain.value) return false; + + const checkForDomains = [{ + domain: domain.value, + subdomain: subdomain.value, + }]; + + for (const d in secondaryDomains.value) checkForDomains.push({ domain: secondaryDomains.value[d].domain, subdomain: secondaryDomains.value[d].subdomain }); + for (const d of aliases.value) checkForDomains.push({ domain: d.domain, subdomain: d.subdomain }); + for (const d of redirects.value) checkForDomains.push({ domain: d.domain, subdomain: d.subdomain }); + + if (checkForDomains.find(d => !isValidDomain((d.subdomain ? (d.subdomain + '.') : '') + d.domain))) return false; + + return true; +}); + function onRemoveRedirect(index) { redirects.value.splice(index, 1); } @@ -161,7 +179,7 @@ onMounted(async () => {
- + @@ -228,6 +246,6 @@ onMounted(async () => {
- +