diff --git a/.dockerignore b/.dockerignore index 876e20a..74f83e1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,5 +22,6 @@ next-env.d.ts *.log .machinelogs*.json *-audit.json -config package-lock.json +config/ +install/ \ No newline at end of file diff --git a/install/main.go b/install/main.go index b2d0d79..39c3d29 100644 --- a/install/main.go +++ b/install/main.go @@ -11,6 +11,7 @@ import ( "runtime" "strings" "text/template" + "unicode" ) //go:embed fs/* @@ -99,7 +100,19 @@ func collectUserInput(reader *bufio.Reader) Config { // Admin user configuration fmt.Println("\n=== Admin User Configuration ===") config.AdminUserEmail = readString(reader, "Enter admin user email", "admin@"+config.Domain) - config.AdminUserPassword = readString(reader, "Enter admin user password", "") + for { + config.AdminUserPassword = readString(reader, "Enter admin user password", "") + if valid, message := validatePassword(config.AdminUserPassword); valid { + break + } else { + fmt.Println("Invalid password:", message) + fmt.Println("Password requirements:") + fmt.Println("- At least one uppercase English letter") + fmt.Println("- At least one lowercase English letter") + fmt.Println("- At least one digit") + fmt.Println("- At least one special character") + } + } // Security settings fmt.Println("\n=== Security Settings ===") @@ -135,6 +148,52 @@ func collectUserInput(reader *bufio.Reader) Config { return config } +func validatePassword(password string) (bool, string) { + if len(password) == 0 { + return false, "Password cannot be empty" + } + + var ( + hasUpper bool + hasLower bool + hasDigit bool + hasSpecial bool + ) + + for _, char := range password { + switch { + case unicode.IsUpper(char): + hasUpper = true + case unicode.IsLower(char): + hasLower = true + case unicode.IsDigit(char): + hasDigit = true + case unicode.IsPunct(char) || unicode.IsSymbol(char): + hasSpecial = true + } + } + + var missing []string + if !hasUpper { + missing = append(missing, "an uppercase letter") + } + if !hasLower { + missing = append(missing, "a lowercase letter") + } + if !hasDigit { + missing = append(missing, "a digit") + } + if !hasSpecial { + missing = append(missing, "a special character") + } + + if len(missing) > 0 { + return false, fmt.Sprintf("Password must contain %s", strings.Join(missing, ", ")) + } + + return true, "" +} + func createConfigFiles(config Config) error { os.MkdirAll("config", 0755) os.MkdirAll("config/letsencrypt", 0755)