diff --git a/changelog.md b/changelog.md index ce62518..febd9e1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,11 @@ -## version 0.8.1 -> 0.8.2 +## version 0.8.1 -> 0.8.3 + - Added new automatic Docker mapping feature (for people not using (sub)domains) - App store image size issue - - Add installer hostname prefix/suffix - - Fix issue with inconsistent password when installing from the market + - Add installer option for hostname prefix/suffix + - Fix minor issue with inconsistent password on market installer + - Fixed issue where home page was https:// links on http only servers + - Improved setup flow for setting up hostname and HTTPS + - Added a new port range system for people not using a domain name ## Version 0.8.0 - Custmizable homepage / theme colors diff --git a/client/src/pages/config/users/configman.jsx b/client/src/pages/config/users/configman.jsx index 8f5706d..d86ecb0 100644 --- a/client/src/pages/config/users/configman.jsx +++ b/client/src/pages/config/users/configman.jsx @@ -337,7 +337,7 @@ const ConfigManagement = () => { - Hostname: This will be used to restrict access to your Cosmos Server (Default: 0.0.0.0) + Hostname: This will be used to restrict access to your Cosmos Server (Your IP, or your domain name) { {coStatus && coStatus.domain && ( - You are using localhost or 0.0.0.0 as a hostname in the configuration. It is recommended that you use a domain name instead. + You are using localhost or 0.0.0.0 as a hostname in the configuration. It is recommended that you use a domain name or an IP instead. )} diff --git a/client/src/pages/newInstall/newInstall.jsx b/client/src/pages/newInstall/newInstall.jsx index 6cede60..6baa9d8 100644 --- a/client/src/pages/newInstall/newInstall.jsx +++ b/client/src/pages/newInstall/newInstall.jsx @@ -47,6 +47,8 @@ const debounce = (func, wait) => { } }, 500) +const hostnameIsDomainReg = /^((?!localhost|\d+\.\d+\.\d+\.\d+)[a-zA-Z0-9\-]{1,63}\.)+[a-zA-Z]{2,63}$/ + const NewInstall = () => { const [activeStep, setActiveStep] = useState(0); const [status, setStatus] = useState(null); @@ -83,6 +85,29 @@ const NewInstall = () => { } }, [activeStep, status]); + const getHTTPSOptions = (hostname) => { + if(!hostname) { + return [["", "Set your hostname first"]]; + } + + if(hostname.match(hostnameIsDomainReg)) { + return [ + ["", "Select an option"], + ["LETSENCRYPT", "Use Let's Encrypt automatic HTTPS (recommended)"], + ["SELFSIGNED", "Generate self-signed certificate"], + ["PROVIDED", "Supply my own HTTPS certificate"], + ["DISABLED", "Use HTTP only (not recommended)"], + ] + } else { + return [ + ["", "Select an option"], + ["SELFSIGNED", "Generate self-signed certificate (recommended)"], + ["PROVIDED", "Supply my own HTTPS certificate"], + ["DISABLED", "Use HTTP only (not recommended)"], + ] + } + } + const steps = [ { label: 'Welcome! 💖', @@ -252,26 +277,17 @@ const NewInstall = () => { component: (
It is recommended to use Let's Encrypt to automatically provide HTTPS Certificates. - This requires a valid domain name pointing to this server. If you don't have one, you can use a self-signed certificate. + This requires a valid domain name pointing to this server. If you don't have one, you can select "Generate self-signed certificate" in the dropdown. If you enable HTTPS, it will be effective after the next restart.
-
- {status && <> -
- HTTPS Certificate Mode is currently: {status.HTTPSCertificateMode} -
-
- Hostname is currently: {status.hostname} -
- } -
{ }), Hostname: Yup.string().when('HTTPSCertificateMode', { is: "LETSENCRYPT", - then: Yup.string().required().matches(/^((?!localhost|\d+\.\d+\.\d+\.\d+)[a-zA-Z0-9\-]{1,63}\.)+[a-zA-Z]{2,63}$/, 'Let\'s Encrypt only accepts domain names'), + then: Yup.string().required().matches(hostnameIsDomainReg, 'Let\'s Encrypt only accepts domain names'), otherwise: Yup.string().required() }), })} @@ -310,7 +326,9 @@ const NewInstall = () => { if(res.status == "OK") { setStatus({ success: true }); setHostname((values.HTTPSCertificateMode == "DISABLED" ? "http://" : "https://") + values.Hostname); + setActiveStep(4); } + return res; } catch (error) { setStatus({ success: false }); setErrors({ submit: "Please check you have filled all the inputs properly" }); @@ -320,16 +338,31 @@ const NewInstall = () => { {(formik) => (
+ { + checkHost(e.target.value, setHostError, setHostIp); + }} + /> + {formik.values.Hostname && (formik.values.Hostname.match(hostnameIsDomainReg) ? + + You seem to be using a domain name.
+ Let's Encrypt can automatically generate a certificate for you. +
+ : + + You seem to be using an IP address or local domain.
+ You can use automatic Self-Signed certificates. +
) + } {formik.values.HTTPSCertificateMode === "LETSENCRYPT" && ( <> @@ -378,15 +411,6 @@ const NewInstall = () => { )} - { - checkHost(e.target.value, setHostError, setHostIp); - }} - /> {hostError && {hostError} } @@ -401,11 +425,12 @@ const NewInstall = () => { )} + {(formik.values.HTTPSCertificateMode === "LETSENCRYPT" || formik.values.HTTPSCertificateMode === "SELFSIGNED") && formik.values.Hostname && formik.values.Hostname.match(hostnameIsDomainReg) && ( + />)} {formik.errors.submit && ( @@ -432,7 +457,7 @@ const NewInstall = () => {
), nextButtonLabel: () => { - return status ? 'Next' : 'Skip'; + return (status && status.hostname != '0.0.0.0') ? 'Next' : ''; } }, { diff --git a/client/src/pages/servapps/containers/docker-compose.jsx b/client/src/pages/servapps/containers/docker-compose.jsx index c028624..8b69404 100644 --- a/client/src/pages/servapps/containers/docker-compose.jsx +++ b/client/src/pages/servapps/containers/docker-compose.jsx @@ -32,7 +32,7 @@ import DockerContainerSetup from './setup'; import whiskers from 'whiskers'; import {version} from '../../../../../package.json'; import cmp from 'semver-compare'; -import { HostnameChecker } from '../../../utils/routes'; +import { HostnameChecker, getHostnameFromName } from '../../../utils/routes'; import { CosmosContainerPicker } from '../../config/users/containerPicker'; import { randomString } from '../../../utils/indexs'; @@ -76,10 +76,6 @@ const isNewerVersion = (minver) => { return cmp(version, minver) === -1; } -const getHostnameFromName = (name) => { - return name.replace('/', '').replace(/_/g, '-').replace(/[^a-zA-Z0-9-]/g, '').toLowerCase().replace(/\s/g, '-') + '.' + window.location.origin.split('://')[1] -} - const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaultName }) => { const cleanDefaultName = defaultName && defaultName.replace(/\s/g, '-').replace(/[^a-zA-Z0-9-]/g, ''); const [step, setStep] = useState(0); @@ -94,6 +90,19 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul const [context, setContext] = useState({}); const [installer, setInstaller] = useState(installerInit); const [config, setConfig] = useState({}); + + let hostnameErrors = () => { + let broken = false; + Object.values(hostnames).forEach((service) => { + Object.values(service).forEach((route) => { + if(!route.host || route.host.match(/\s/g)) { + broken = true; + } + }); + }); + return broken; + } + const [passwords, setPasswords] = useState([ randomString(24), randomString(24), @@ -369,7 +378,7 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul if (route.useHost) { let newRoute = Object.assign({}, route); if (route.useHost === true) { - newRoute.host = (newRoute.hostPrefix || '') + getHostnameFromName(key + (routeId > 0 ? '-' + routeId : '')) + (newRoute.hostSuffix || ''); + newRoute.host = getHostnameFromName(key + (routeId > 0 ? '-' + routeId : ''), newRoute, config); } if(!newHostnames[key]) newHostnames[key] = {}; @@ -722,7 +731,7 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul setHostnames({}); setOverrides({}); }}>Close -