浏览代码

[release] v0.7.6

Yann Stepienik 2 年之前
父节点
当前提交
10abffbf26

+ 4 - 1
changelog.md

@@ -1,4 +1,7 @@
-## Version 0.7.1 -> 0.7.5
+## Version 0.7.1 -> 0.7.6
+ - Add more special characters to be used for password validation
+ - Add configurable default data path for binds
+ - Remove Redirects from home page
  - Fix compat with non-HTTP protocol like WebDAV (for Nextcloud for example)
  - Fix regression with DNS wildcards certificates
  - Fix issue with the installer when changing both the labels and the volumes

+ 2 - 2
client/src/pages/authentication/auth-forms/AuthRegister.jsx

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

+ 25 - 0
client/src/pages/config/users/configman.jsx

@@ -80,6 +80,9 @@ const ConfigManagement = () => {
           Email_Password: config.EmailConfig.Password,
           Email_From: config.EmailConfig.From,
           Email_UseTLS : config.EmailConfig.UseTLS,
+
+          SkipPruneNetwork: config.DockerConfig.SkipPruneNetwork,
+          DefaultDataPath: config.DockerConfig.DefaultDataPath
         }}
         validationSchema={Yup.object().shape({
           Hostname: Yup.string().max(255).required('Hostname is required'),
@@ -116,6 +119,11 @@ const ConfigManagement = () => {
                 Password: values.Email_Password,
                 From: values.Email_From,
                 UseTLS: values.Email_UseTLS,
+              },
+              DockerConfig: {
+                ...config.DockerConfig,
+                SkipPruneNetwork: values.SkipPruneNetwork,
+                DefaultDataPath: values.DefaultDataPath
               }
             }
             
@@ -353,6 +361,23 @@ const ConfigManagement = () => {
                 </Stack>
               </MainCard>
 
+              <MainCard title="Docker">
+                <Stack spacing={2}>
+                  <CosmosCheckbox
+                    label="Skip Prune Network"
+                    name="SkipPruneNetwork"
+                    formik={formik}
+                  />
+
+                  <CosmosInputText
+                    label="Default data path for installs"
+                    name="DefaultDataPath"
+                    formik={formik}
+                  />
+                </Stack>
+              </MainCard>
+
+
               <MainCard title="Security">
                   <Grid container spacing={3}>
                   

+ 1 - 1
client/src/pages/home/index.jsx

@@ -167,7 +167,7 @@ const HomePage = () => {
 
         <Grid2 container spacing={2} style={{ zIndex: 2 }}>
             {config && serveApps && routes.map((route) => {
-                let skip = false;
+                let skip = route.Mode == "REDIRECT";
                 if(route.Mode == "SERVAPP") {
                     const containerName = route.Target.split(':')[1].slice(2);
                     const container = serveApps.find((c) => c.Names.includes('/' + containerName));

+ 1 - 1
client/src/pages/newInstall/newInstall.jsx

@@ -455,7 +455,7 @@ const NewInstall = () => {
                         // nickname cant be admin or root
                         nickname: Yup.string().required('Nickname is required').min(3).max(32)
                         .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),
                         confirmPassword: Yup.string().oneOf([Yup.ref('password'), null], 'Passwords must match'),
                     })}

+ 17 - 4
client/src/pages/servapps/containers/docker-compose.jsx

@@ -93,6 +93,17 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul
   const [overrides, setOverrides] = useState({});
   const [context, setContext] = useState({});
   const [installer, setInstaller] = useState(installerInit);
+  const [config, setConfig] = useState({});
+
+  function refreshConfig() {
+    API.config.get().then((res) => {
+      setConfig(res.data);
+    });
+  }
+
+  React.useEffect(() => {
+    refreshConfig();
+  }, []);
 
   useEffect(() => {
     if (!openModal) {
@@ -325,12 +336,14 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul
           Hostnames: hostnames,
           Context: context,
           Passwords: [
-            randomString(32),
-            randomString(32),
-            randomString(32)
+            randomString(24),
+            randomString(24),
+            randomString(24),
+            randomString(24)
           ],
           CPU_ARCH: API.CPU_ARCH,
           CPU_AVX: API.CPU_AVX,
+          DefaultDataPath: (config && config.DockerConfig && config.DockerConfig.DefaultDataPath) || "/usr",
         });
 
         const jsoned = JSON.parse(rendered);
@@ -441,7 +454,7 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul
       setYmlError(e.message);
       return;
     }
-  }, [openModal, dockerCompose, serviceName, hostnames, overrides, installer]);
+  }, [openModal, dockerCompose, serviceName, hostnames, overrides, installer, config]);
 
   const openModalFunc = () => {
     setOpenModal(true);

+ 1 - 1
client/src/utils/password-strength.jsx

@@ -5,7 +5,7 @@ const hasNumber = (number) => new RegExp(/[0-9]/).test(number);
 const hasMixed = (number) => new RegExp(/[a-z]/).test(number) && new RegExp(/[A-Z]/).test(number);
 
 // has special chars
-const hasSpecial = (number) => new RegExp(/[!#@$%^&*)(+=._-]/).test(number);
+const hasSpecial = (number) => new RegExp(/[~!@#$%\^&\*\(\)_\+=\-\{\[\}\]:;"'<,>\.\?\/]/).test(number);
 
 // set color based on password strength
 export const strengthColor = (count) => {

+ 1 - 1
package.json

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

+ 1 - 1
src/newInstall.go

@@ -39,7 +39,7 @@ type NewInstallJSON struct {
 
 type AdminJSON struct {
 	Nickname string `validate:"required,min=3,max=32,alphanum"`
-	Password string `validate:"required,min=9,max=128,containsany=!@#$%^&*()_+,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
+	Password string `validate:"required,min=9,max=128,containsany=~!@#$%^&*()_+=-{[}]:;"'<>.?/,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
 }
 
 func NewInstallRoute(w http.ResponseWriter, req *http.Request) {

+ 1 - 1
src/user/login.go

@@ -14,7 +14,7 @@ import (
 
 type LoginRequestJSON struct {
 	Nickname string `validate:"required,min=3,max=32,alphanum"`
-	Password string `validate:"required,min=8,max=128,containsany=!@#$%^&*()_+,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
+	Password string `validate:"required,min=8,max=128,containsany=~!@#$%^&*()_+=-{[}]:;"'<>.?/,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
 }
 
 func UserLogin(w http.ResponseWriter, req *http.Request) {

+ 1 - 1
src/user/register.go

@@ -13,7 +13,7 @@ import (
 
 type RegisterRequestJSON struct {
 	Nickname string `validate:"required,min=3,max=32,alphanum"`
-	Password string `validate:"required,min=9,max=128,containsany=!@#$%^&*()_+,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
+	Password string `validate:"required,min=9,max=128,containsany=~!@#$%^&*()_+=-{[}]:;"'<>.?/,containsany=ABCDEFGHIJKLMNOPQRSTUVWXYZ,containsany=abcdefghijklmnopqrstuvwxyz,containsany=0123456789"`
 	RegisterKey string `validate:"required,min=1,max=512,alphanum"`
 }
 

+ 1 - 0
src/utils/types.go

@@ -126,6 +126,7 @@ type SmartShieldPolicy struct {
 
 type DockerConfig struct {
 	SkipPruneNetwork bool
+	DefaultDataPath string
 }
 
 type ProxyConfig struct {

+ 6 - 3
src/utils/utils.go

@@ -78,6 +78,9 @@ var DefaultConfig = Config{
 			Routes: []ProxyRouteConfig{},
 		},
 	},
+	DockerConfig: DockerConfig{
+		DefaultDataPath: "/usr",
+	},
   MarketConfig: MarketConfig{
     Sources: []MarketSource{
 		},
@@ -216,9 +219,9 @@ func LoadBaseMainConfig(config Config) {
 		MainConfig.ServerCountry = os.Getenv("COSMOS_SERVER_COUNTRY")
 	}
 	
-	// if BaseMainConfig.NewInstall {
-	// 	MainConfig.HTTPConfig.HTTPSCertificateMode = "DISABLED"
-	// }
+	if MainConfig.DockerConfig.DefaultDataPath == "" {
+		MainConfig.DockerConfig.DefaultDataPath = "/usr"
+	}
 }
 
 func GetMainConfig() Config {