[release] v0.9.5

This commit is contained in:
Yann Stepienik 2023-07-07 11:36:27 +01:00
parent 6976f4d99d
commit 43a9ddef08
10 changed files with 128 additions and 92 deletions

View file

@ -1,8 +1,11 @@
## Version 0.9.1 > 0.9.4 ## Version 0.9.1 > 0.9.5
- Fix subdomain logic for composed TLDs - Fix subdomain logic for composed TLDs
- Add option for custom wildcard domains
- Fix domain depupe logic - Fix domain depupe logic
- Add import button in market
- Update LEGO - Update LEGO
- Fix issue with hot-reloading between HTTP and HTTPS - Fix issue with hot-reloading between HTTP and HTTPS
- Fix loading bar in container overview page
## Version 0.9.0 ## Version 0.9.0
- Rewrote the entire HTTPS / DNS challenge system to be more robust and easier to use - Rewrote the entire HTTPS / DNS challenge system to be more robust and easier to use

View file

@ -73,7 +73,7 @@ const AuthRegister = ({nickname, isRegister, isInviteLink, regkey}) => {
.max(255) .max(255)
.required('Password is required') .required('Password is required')
.matches( .matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%\^&\*\(\)_\+=\-\{\[\}\]:;"'<,>\.\?\/])(?=.{9,})/, /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%\^&\*\(\)_\+=\-\{\[\}\]:;"'<,>\.\/])(?=.{9,})/,
'Must Contain 9 Characters, One Uppercase, One Lowercase, One Number and one special case Character (~!@#$%^&*()_+=-{[}]:;"\'<>.?/)' 'Must Contain 9 Characters, One Uppercase, One Lowercase, One Number and one special case Character (~!@#$%^&*()_+=-{[}]:;"\'<>.?/)'
), ),
})} })}

View file

@ -90,6 +90,7 @@ const ConfigManagement = () => {
DNSChallengeProvider: config.HTTPConfig.DNSChallengeProvider, DNSChallengeProvider: config.HTTPConfig.DNSChallengeProvider,
DNSChallengeConfig: config.HTTPConfig.DNSChallengeConfig, DNSChallengeConfig: config.HTTPConfig.DNSChallengeConfig,
ForceHTTPSCertificateRenewal: config.HTTPConfig.ForceHTTPSCertificateRenewal, ForceHTTPSCertificateRenewal: config.HTTPConfig.ForceHTTPSCertificateRenewal,
OverrideWildcardDomains: config.HTTPConfig.OverrideWildcardDomains,
Email_Enabled: config.EmailConfig.Enabled, Email_Enabled: config.EmailConfig.Enabled,
Email_Host: config.EmailConfig.Host, Email_Host: config.EmailConfig.Host,
@ -136,6 +137,7 @@ const ConfigManagement = () => {
DNSChallengeProvider: values.DNSChallengeProvider, DNSChallengeProvider: values.DNSChallengeProvider,
DNSChallengeConfig: values.DNSChallengeConfig, DNSChallengeConfig: values.DNSChallengeConfig,
ForceHTTPSCertificateRenewal: values.ForceHTTPSCertificateRenewal, ForceHTTPSCertificateRenewal: values.ForceHTTPSCertificateRenewal,
OverrideWildcardDomains: values.OverrideWildcardDomains.replace(/\s/g, ''),
}, },
EmailConfig: { EmailConfig: {
...config.EmailConfig, ...config.EmailConfig,
@ -552,6 +554,19 @@ const ConfigManagement = () => {
formik={formik} formik={formik}
/> />
{formik.values.UseWildcardCertificate && (
<CosmosInputText
name="OverrideWildcardDomains"
onChange={(e) => {
formik.setFieldValue("ForceHTTPSCertificateRenewal", true);
}}
label="(optional) Override Wildcard Domains (comma separated, need to add both wildcard AND root domain like in the placeholder)"
formik={formik}
placeholder={"example.com,*.example.com"}
/>
)}
{formik.values.HTTPSCertificateMode === "LETSENCRYPT" && ( {formik.values.HTTPSCertificateMode === "LETSENCRYPT" && (
<CosmosInputText <CosmosInputText
name="SSLEmail" name="SSLEmail"

View file

@ -10,7 +10,8 @@ import { Paper, Button , Chip} from '@mui/material'
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Link as LinkMUI } from '@mui/material' import { Link as LinkMUI } from '@mui/material'
import DockerComposeImport from '../servapps/containers/docker-compose'; import DockerComposeImport from '../servapps/containers/docker-compose';
import { SearchOutlined } from "@ant-design/icons"; import { AppstoreAddOutlined, SearchOutlined } from "@ant-design/icons";
import ResponsiveButton from "../../components/responseiveButton";
function Screenshots({ screenshots }) { function Screenshots({ screenshots }) {
return screenshots.length > 1 ? ( return screenshots.length > 1 ? (
@ -234,6 +235,7 @@ const MarketPage = () => {
padding: '24px', padding: '24px',
}}> }}>
<h2>Applications</h2> <h2>Applications</h2>
<Stack direction="row" spacing={2}>
<Input placeholder="Search" <Input placeholder="Search"
value={search} value={search}
style={{ maxWidth: '400px' }} style={{ maxWidth: '400px' }}
@ -246,6 +248,15 @@ const MarketPage = () => {
setSearch(e.target.value); setSearch(e.target.value);
}} }}
/> />
<Link to="/cosmos-ui/servapps/new-service">
<ResponsiveButton
variant="contained"
startIcon={<AppstoreAddOutlined />}
>Start ServApp</ResponsiveButton>
</Link>
<DockerComposeImport refresh={() => { }} />
</Stack>
{(!apps || !Object.keys(apps).length) && <Box style={{ {(!apps || !Object.keys(apps).length) && <Box style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
@ -289,11 +300,13 @@ const MarketPage = () => {
}} }}
>{app.description}</div> >{app.description}</div>
<Stack direction={'row'} spacing={1}> <Stack direction={'row'} spacing={1}>
<div style={{ fontStyle: "italic", opacity: 0.7, <div style={{
fontStyle: "italic", opacity: 0.7,
overflow: 'hidden', overflow: 'hidden',
height: '21px', height: '21px',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
whiteSpace: 'pre-wrap', }}>{app.tags.slice(0,3).join(", ")}</div> whiteSpace: 'pre-wrap',
}}>{app.tags.slice(0, 3).join(", ")}</div>
</Stack> </Stack>
</Stack> </Stack>
</Stack> </Stack>

View file

@ -485,7 +485,7 @@ const NewInstall = () => {
// nickname cant be admin or root // nickname cant be admin or root
nickname: Yup.string().required('Nickname is required').min(3).max(32) nickname: Yup.string().required('Nickname is required').min(3).max(32)
.matches(/^(?!admin|root).*$/, 'Nickname cannot be admin or root'), .matches(/^(?!admin|root).*$/, 'Nickname cannot be admin or root'),
password: Yup.string().required('Password is required').min(8).max(128).matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%\^&\*\(\)_\+=\-\{\[\}\]:;"'<,>\.\?\/])(?=.{9,})/, 'Password must contain 9 characters: at least 1 lowercase, 1 uppercase, 1 number, and 1 special character'), password: Yup.string().required('Password is required').min(8).max(128).matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%\^&\*\(\)_\+=\-\{\[\}\]:;"'<,>\.\/])(?=.{9,})/, 'Password must contain 9 characters: at least 1 lowercase, 1 uppercase, 1 number, and 1 special character'),
email: Yup.string().email('Must be a valid email').max(255), email: Yup.string().email('Must be a valid email').max(255),
confirmPassword: Yup.string().oneOf([Yup.ref('password'), null], 'Passwords must match'), confirmPassword: Yup.string().oneOf([Yup.ref('password'), null], 'Passwords must match'),
})} })}

View file

@ -496,9 +496,7 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul
<DialogContent style={{ width: '800px', maxWidth: '100%' }}> <DialogContent style={{ width: '800px', maxWidth: '100%' }}>
<DialogContentText> <DialogContentText>
{step === 0 && !installer && <><Stack spacing={2}> {step === 0 && !installer && <><Stack spacing={2}>
<Alert severity="warning" icon={<WarningOutlined />}>
This is an experimental feature. It is recommended to use with caution. Please report any issue you find!
</Alert>
<UploadButtons <UploadButtons
accept='.yml,.yaml,.json' accept='.yml,.yaml,.json'

View file

@ -30,9 +30,9 @@ const ContainerOverview = ({ containerInfo, config, refresh, updatesAvailable, s
const healthIconColor = healthStatus === 'Healthy' ? 'green' : 'red'; const healthIconColor = healthStatus === 'Healthy' ? 'green' : 'red';
const routes = getContainersRoutes(config, Name.replace('/', '')); const routes = getContainersRoutes(config, Name.replace('/', ''));
let refreshAll = refresh && (() => refresh().then(() => { let refreshAll = refresh ? (() => refresh().then(() => {
setIsUpdating(false); setIsUpdating(false);
})); })) : (() => {setIsUpdating(false);});
const updateRoutes = (newRoute) => { const updateRoutes = (newRoute) => {
API.config.addRoute(newRoute).then(() => { API.config.addRoute(newRoute).then(() => {
@ -95,6 +95,7 @@ const ContainerOverview = ({ containerInfo, config, refresh, updatesAvailable, s
image={Image} image={Image}
state={State.Status} state={State.Status}
refreshServApps={() => { refreshServApps={() => {
setIsUpdating(false);
refreshAll() refreshAll()
}} }}
setIsUpdatingId={() => { setIsUpdatingId={() => {

View file

@ -1,6 +1,6 @@
{ {
"name": "cosmos-server", "name": "cosmos-server",
"version": "0.9.4", "version": "0.9.5",
"description": "", "description": "",
"main": "test-server.js", "main": "test-server.js",
"bugs": { "bugs": {

View file

@ -119,6 +119,7 @@ type HTTPConfig struct {
Hostname string `validate:"required,excludesall=0x2C/ "` Hostname string `validate:"required,excludesall=0x2C/ "`
SSLEmail string `validate:"omitempty,email"` SSLEmail string `validate:"omitempty,email"`
UseWildcardCertificate bool UseWildcardCertificate bool
OverrideWildcardDomains string `validate:"omitempty,excludesall=/ "`
AcceptAllInsecureHostname bool AcceptAllInsecureHostname bool
DNSChallengeConfig map[string]string `json:"DNSChallengeConfig,omitempty"` DNSChallengeConfig map[string]string `json:"DNSChallengeConfig,omitempty"`
} }

View file

@ -330,6 +330,7 @@ func LetsEncryptValidOnly(hostnames []string, acceptWildcard bool) []string {
func GetAllHostnames(applyWildCard bool, removePorts bool) []string { func GetAllHostnames(applyWildCard bool, removePorts bool) []string {
mainHostname := GetMainConfig().HTTPConfig.Hostname mainHostname := GetMainConfig().HTTPConfig.Hostname
OverrideWildcardDomains := GetMainConfig().HTTPConfig.OverrideWildcardDomains
if removePorts { if removePorts {
mainHostname = strings.Split(mainHostname, ":")[0] mainHostname = strings.Split(mainHostname, ":")[0]
@ -370,6 +371,10 @@ func GetAllHostnames(applyWildCard bool, removePorts bool) []string {
"*." + bareMainHostname, "*." + bareMainHostname,
} }
if(OverrideWildcardDomains != "") {
filteredHostnames = strings.Split(OverrideWildcardDomains, ",")
}
for _, hostname := range uniqueHostnames { for _, hostname := range uniqueHostnames {
if hostname != bareMainHostname && !strings.HasSuffix(hostname, "." + bareMainHostname) { if hostname != bareMainHostname && !strings.HasSuffix(hostname, "." + bareMainHostname) {
filteredHostnames = append(filteredHostnames, hostname) filteredHostnames = append(filteredHostnames, hostname)