Changemaker/config.sh

781 lines
26 KiB
Bash
Executable File

#!/bin/bash
cat << "EOF"
██████╗██╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ███████╗
██╔════╝██║ ██║██╔══██╗████╗ ██║██╔════╝ ██╔════╝
██║ ███████║███████║██╔██╗ ██║██║ ███╗█████╗
██║ ██╔══██║██╔══██║██║╚██╗██║██║ ██║██╔══╝
╚██████╗██║ ██║██║ ██║██║ ╚████║╚██████╔╝███████╗
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
███╗ ███╗ █████╗ ██╗ ██╗███████╗██████╗
████╗ ████║██╔══██╗██║ ██╔╝██╔════╝██╔══██╗
██╔████╔██║███████║█████╔╝ █████╗ ██████╔╝
██║╚██╔╝██║██╔══██║██╔═██╗ ██╔══╝ ██╔══██╗
██║ ╚═╝ ██║██║ ██║██║ ██╗███████╗██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
Configuration Wizard
EOF
# Get the absolute path of the script directory
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ENV_FILE="$SCRIPT_DIR/.env"
SERVICES_YAML="$SCRIPT_DIR/configs/homepage/services.yaml"
WIDGETS_YAML="$SCRIPT_DIR/configs/homepage/widgets.yaml"
MKDOCS_MAIN_HTML="$SCRIPT_DIR/mkdocs/docs/overrides/main.html"
MKDOCS_YML="$SCRIPT_DIR/mkdocs/mkdocs.yml"
echo "Looking for .env file at: $ENV_FILE"
# Initialize a new .env file if it doesn't exist
if [ ! -f "$ENV_FILE" ]; then
echo "No .env file found. Creating a new one from scratch."
touch "$ENV_FILE"
initialize_env_file
else
echo "Found existing .env file. Will update values."
# Create a backup of the existing file
backup_env_file
fi
# Function to update the services.yaml file with the new domain
update_services_yaml() {
local new_domain=$1
if [ ! -f "$SERVICES_YAML" ]; then
echo "Warning: services.yaml file not found at $SERVICES_YAML"
return 1
fi
echo "Updating service URLs in services.yaml..."
# Create a backup of the services.yaml file
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${SERVICES_YAML}.backup_${timestamp}"
cp "$SERVICES_YAML" "$backup_file"
echo "Created backup of services.yaml at $backup_file"
# Get the content of the services.yaml file
local content=$(cat "$SERVICES_YAML")
# Extract all unique domains from the file using grep with a more robust pattern
local domains=$(echo "$content" | grep -o 'https://[^[:space:]"]*' | cut -d'/' -f3 | sort | uniq)
# Check if we found any domains
if [ -z "$domains" ]; then
echo "Warning: Could not find any URLs in services.yaml"
return 1
fi
echo "Found these domains in services.yaml:"
echo "$domains"
# Extract the base domain pattern (e.g., betteredmonton.org)
local base_domain_pattern=$(echo "$domains" | head -1 | sed -E 's/^[^.]+\.//')
if [ -z "$base_domain_pattern" ]; then
echo "Warning: Could not extract base domain pattern from URLs"
return 1
fi
echo "Detected base domain pattern: $base_domain_pattern"
echo "Will replace with: $new_domain"
# Create a temporary file for the updated content
local temp_file=$(mktemp)
# Replace domain in all URLs
if ! echo "$content" | sed "s|$base_domain_pattern|$new_domain|g" > "$temp_file"; then
echo "Error: Failed to update domains in the file"
rm -f "$temp_file"
return 1
fi
# Check if the file has any changes
if ! grep -q "$new_domain" "$temp_file"; then
echo "Warning: No domain replacements were made. Check the domain pattern matching."
cat "$temp_file" | grep -o 'https://[^[:space:]"]*' | head -5
rm -f "$temp_file"
return 1
fi
# Count the number of URLs with the new domain
local replacements=$(grep -o "https://[^[:space:]\"]*$new_domain" "$temp_file" | wc -l)
# Move the modified file to replace the original
mv "$temp_file" "$SERVICES_YAML"
echo "Updated $replacements URLs in services.yaml to use $new_domain"
echo "Examples of updated URLs:"
grep -o "https://[^[:space:]\"]*$new_domain" "$SERVICES_YAML" | head -5
return 0
}
# Function to update the login URL in MkDocs main.html
update_mkdocs_main_html() {
local new_domain=$1
if [ ! -f "$MKDOCS_MAIN_HTML" ]; then
echo "Warning: MkDocs main.html not found at $MKDOCS_MAIN_HTML"
return 1
fi
echo "Updating login button URL in MkDocs main.html..."
# Create a backup of the main.html file
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${MKDOCS_MAIN_HTML}.backup_${timestamp}"
cp "$MKDOCS_MAIN_HTML" "$backup_file"
echo "Created backup of main.html at $backup_file"
# Create a new file for the modified content
local new_file="${MKDOCS_MAIN_HTML}.new"
# Extract the current login URL from the login button
local login_line=$(grep -A 1 "{% block announce %}" "$MKDOCS_MAIN_HTML" | grep "login-button")
local current_url=$(echo "$login_line" | grep -o 'https://[^"]*')
if [ -z "$current_url" ] || [ -z "$login_line" ]; then
echo "Warning: Could not find the login button URL in main.html"
return 1
fi
# Create the replacement login line with the new domain
local new_login_line=$(echo "$login_line" | sed "s|$current_url|https://homepage.$new_domain|g")
# Create the new file by replacing the login line
while IFS= read -r line; do
if [[ "$line" == "$login_line" ]]; then
echo "$new_login_line" >> "$new_file"
else
echo "$line" >> "$new_file"
fi
done < "$MKDOCS_MAIN_HTML"
# Move the new file to replace the original
mv "$new_file" "$MKDOCS_MAIN_HTML"
echo "Updated login button URL in main.html from '$current_url' to 'https://homepage.$new_domain'"
return 0
}
# Function to create a timestamped backup of the .env file
backup_env_file() {
if [ -f "$ENV_FILE" ]; then
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="$ENV_FILE.backup_$timestamp"
echo "Creating backup of current .env file to: $backup_file"
if cp "$ENV_FILE" "$backup_file"; then
echo "Backup created successfully!"
return 0
else
echo "Failed to create backup file. Proceeding with caution..."
return 1
fi
fi
}
# Function to initialize the .env file with default values
initialize_env_file() {
echo "Initializing new .env file with default values..."
# Create the new .env file with header
cat > "$ENV_FILE" << EOL
# Never share this file publicly. It contains sensitive information.
# This file is used to configure various applications and services.
# Generated by Changemaker Config Wizard on $(date)
# Domain Configuration
DOMAIN=changeme.org
BASE_DOMAIN=https://changeme.org
# Listmonk Configuration
LISTMONK_ADMIN_USER=admin
LISTMONK_ADMIN_PASSWORD=strongpassword
LISTMONK_PORT=9000
LISTMONK_HOSTNAME=listmonk.changeme.org
# Database Credentials
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=$(generate_password 20)
POSTGRES_DB=listmonk
# Monica CRM Configuration
MONICA_APP_KEY=base64:$(openssl rand -base64 32)
MONICA_DB_USERNAME=monica
MONICA_DB_PASSWORD=$(generate_password 20)
MONICA_MYSQL_DATABASE=monica
MONICA_MYSQL_USER=monica
MONICA_MYSQL_PASSWORD=$(generate_password 20)
# MkDocs Configuration
USER_ID=1000
GROUP_ID=1000
MKDOCS_PORT=4000
# Flatnotes Configuration
FLATNOTES_PUID=1000
FLATNOTES_PGID=1000
FLATNOTES_AUTH_TYPE=password
FLATNOTES_USERNAME=user
FLATNOTES_PASSWORD=changeMe!
FLATNOTES_SECRET_KEY=$(generate_password 32)
FLATNOTES_PORT=8089
# Gitea Configuration
GITEA_DB_TYPE=mysql
GITEA_DB_HOST=gitea-db:3306
GITEA_DB_NAME=gitea
GITEA_DB_USER=gitea
GITEA_DB_PASSWD=$(generate_password 24)
GITEA_DB_ROOT_PASSWORD=$(generate_password 24)
GITEA_WEB_PORT=3030
GITEA_SSH_PORT=2225
GITEA_ROOT_URL=https://gitea.changeme.org
GITEA_DOMAIN=gitea.changeme.org
# Apache Answer Configuration
ANSWER_APP_PORT=9080
# Excalidraw Configuration
EXCALIDRAW_PORT=3333
EXCALIDRAW_LIBRARY_URL=https://libraries.excalidraw.com
EXCALIDRAW_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
EXCALIDRAW_PUBLIC_URL=https://excalidraw.changeme.org
EXCALIDRAW_PUBLIC_SOCKET_URL=https://excalidraw.changeme.org
# Code Server Configuration
CODE_SERVER_PORT=8888
USER_NAME=coder
# Cloudflare Credentials
CF_AUTH_EMAIL=
CF_API_TOKEN=
CF_ZONE_ID=
CF_TUNNEL_ID=
CF_DOMAIN=changeme.org
# NocoDB Configuration
NOCODB_PORT=8090
NOCODB_JWT_SECRET=$(generate_password 32)
NOCODB_DB_NAME=nocodb
NOCODB_DB_USER=noco
NOCODB_DB_PASSWORD=$(generate_password 20)
# OpenWebUI Configuration
OPEN_WEBUI_PORT=3005
OPEN_WEBUI_URL=https://open-webui.changeme.org
# N8N Configuration
N8N_PORT=5678
N8N_HOST=n8n.changeme.org
N8N_ENCRYPTION_KEY=$(generate_password 32)
N8N_USER_EMAIL=admin@example.com
N8N_USER_PASSWORD=changeMe
GENERIC_TIMEZONE=UTC
# ConvertX Configuration
CONVERTX_PORT=3100
CONVERTX_JWT_SECRET=$(generate_password 48)
# Rocket.Chat Configuration
ROCKETCHAT_IMAGE=registry.rocket.chat/rocketchat/rocket.chat
ROCKETCHAT_RELEASE=latest
ROCKETCHAT_PORT=3004
ROCKETCHAT_CONTAINER_PORT=3000
ROCKETCHAT_ROOT_URL=https://rocket.changeme.org
ROCKETCHAT_DEPLOYMENT_ENVIRONMENT=changemaker
ROCKETCHAT_MONGODB_VERSION=6.0
ROCKETCHAT_MONGODB_HOST=mongodb-rocketchat
ROCKETCHAT_MONGODB_PORT=27017
ROCKETCHAT_MONGODB_DATABASE=rocketchat
ROCKETCHAT_MONGODB_REPLICA_SET=rs0
ROCKETCHAT_MONGODB_ENABLE_JOURNAL=true
ROCKETCHAT_MONGODB_ALLOW_EMPTY_PASSWORD=yes
# Additional Configuration
EOL
echo "New .env file created with default values."
}
# Function to generate a random secure password
generate_password() {
local length=${1:-16}
openssl rand -base64 48 | tr -dc 'a-zA-Z0-9!@#$%^&*()-_=+' | head -c "$length"
}
# Function to generate a base64 encoded key for Monica
generate_base64_key() {
local length=${1:-32}
local key=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9!@#$%^&*()-_=+' | head -c "$length")
echo "base64:$(echo -n "$key" | base64)"
}
# Function to safely update environment variables in .env file
update_env_var() {
local key=$1
local value=$2
local escaped_value=$(echo "$value" | sed 's/[\/&]/\\&/g')
# Make a temporary backup of the .env file before modification
cp "$ENV_FILE" "$ENV_FILE.bak_tmp"
if grep -q "^$key=" "$ENV_FILE"; then
# Use perl instead of sed for better handling of paths with spaces
perl -i -pe "s/^$key=.*/$key=$escaped_value/" "$ENV_FILE"
echo "Updated $key in .env file"
else
echo "$key=$escaped_value" >> "$ENV_FILE"
echo "Added $key to .env file"
fi
# Check if update was successful
if ! grep -q "^$key=$escaped_value" "$ENV_FILE"; then
echo "Warning: Failed to update $key in .env file"
echo "Restoring from backup..."
cp "$ENV_FILE.bak_tmp" "$ENV_FILE"
echo "Will try alternative method..."
# Alternative update method
local temp_file=$(mktemp)
if grep -q "^$key=" "$ENV_FILE"; then
while IFS= read -r line; do
if [[ $line =~ ^$key= ]]; then
echo "$key=$value" >> "$temp_file"
else
echo "$line" >> "$temp_file"
fi
done < "$ENV_FILE"
else
cat "$ENV_FILE" > "$temp_file"
echo "$key=$value" >> "$temp_file"
fi
mv "$temp_file" "$ENV_FILE"
fi
# Remove the temporary backup file after successful update
rm -f "$ENV_FILE.bak_tmp"
}
# Function to update the greeting widget in widgets.yaml
update_widgets_yaml() {
local new_domain=$1
if [ ! -f "$WIDGETS_YAML" ]; then
echo "Warning: widgets.yaml file not found at $WIDGETS_YAML"
return 1
fi
echo "Updating greeting widget in widgets.yaml..."
# Create a backup of the widgets.yaml file
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${WIDGETS_YAML}.backup_${timestamp}"
cp "$WIDGETS_YAML" "$backup_file"
echo "Created backup of widgets.yaml at $backup_file"
# Extract the site name (domain without TLD) for the greeting text
local site_name=$(echo "$new_domain" | cut -d. -f1)
# Create a temporary file for the modified content
local temp_file=$(mktemp)
# Read the file and replace the greeting text and href
awk -v site_name="$site_name" -v domain="$new_domain" '
/- greeting:/ {
print $0;
getline; print $0; # text_size line
getline; gsub(/text: .*/, "text: " site_name); print $0; # text line
getline; gsub(/href: .*/, "href: https://" domain); print $0; # href line
next;
}
{ print $0; }
' "$WIDGETS_YAML" > "$temp_file"
# Move the temporary file to replace the original
mv "$temp_file" "$WIDGETS_YAML"
echo "Updated greeting widget in widgets.yaml:"
echo " - Set text to: $site_name"
echo " - Set href to: https://$new_domain"
return 0
}
# Function to update the site_url in mkdocs.yml
update_mkdocs_yml() {
local new_domain=$1
if [ ! -f "$MKDOCS_YML" ]; then
echo "Warning: mkdocs.yml not found at $MKDOCS_YML"
return 1
fi
echo "Updating site_url in mkdocs.yml..."
# Create a backup of the mkdocs.yml file
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${MKDOCS_YML}.backup_${timestamp}"
cp "$MKDOCS_YML" "$backup_file"
echo "Created backup of mkdocs.yml at $backup_file"
# Update the site_url value
sed -i "s|^site_url:.*|site_url: https://$new_domain|" "$MKDOCS_YML"
if grep -q "site_url: https://$new_domain" "$MKDOCS_YML"; then
echo "Updated site_url in mkdocs.yml to: https://$new_domain"
return 0
else
echo "Warning: Failed to update site_url in mkdocs.yml"
return 1
fi
}
# Make sure the initialize_env_file function is available
initialize_env_file
echo -e "\n\nWelcome to Changemaker Config!\n"
echo "This script will help you configure your Changemaker instance."
echo "Please provide the following information:"
# Domain configuration
read -p "Enter your domain name (without protocol, e.g., example.com): " domain_name
if [ -z "$domain_name" ]; then
echo "Domain name cannot be empty. Using default: changeme.org"
domain_name="changeme.org"
fi
echo -e "\nUpdating domain settings in .env file at: $ENV_FILE"
# Update main domain settings
update_env_var "DOMAIN" "$domain_name"
update_env_var "BASE_DOMAIN" "https://$domain_name"
# Update Listmonk hostname
update_env_var "LISTMONK_HOSTNAME" "listmonk.$domain_name"
# Update Gitea settings
update_env_var "GITEA_ROOT_URL" "https://gitea.$domain_name"
update_env_var "GITEA_DOMAIN" "gitea.$domain_name"
# Update Excalidraw settings
update_env_var "EXCALIDRAW_PUBLIC_URL" "https://excalidraw.$domain_name"
update_env_var "EXCALIDRAW_PUBLIC_SOCKET_URL" "https://excalidraw.$domain_name"
# Update OpenWebUI settings
echo -e "\nConfiguring OpenWebUI..."
update_env_var "OPEN_WEBUI_PORT" "3005"
update_env_var "OPEN_WEBUI_URL" "https://open-web-ui.$domain_name"
# Update service URLs in the services.yaml file
echo -e "\nUpdating service URLs in services.yaml file..."
update_services_yaml "$domain_name"
# Update the greeting widget in widgets.yaml
echo -e "\nUpdating greeting widget in widgets.yaml..."
update_widgets_yaml "$domain_name"
# After domain configuration and updating services.yaml, update the login button URL
echo -e "\nUpdating login button URL in MkDocs main.html..."
update_mkdocs_main_html "$domain_name"
# Update the site_url in mkdocs.yml
echo -e "\nUpdating site_url in mkdocs.yml..."
update_mkdocs_yml "$domain_name"
echo -e "Domain settings have been updated successfully!\n"
# Listmonk Admin Credentials configuration
echo -e "\n---- Listmonk Admin Credentials ----"
read -p "Enter Listmonk admin username [default: admin]: " listmonk_user
read -sp "Enter Listmonk admin password [default: strongpassword]: " listmonk_password
echo # Add new line after password input
if [ -z "$listmonk_user" ]; then
echo "Using default Listmonk admin username: admin"
listmonk_user="admin"
fi
if [ -z "$listmonk_password" ]; then
echo "Using default Listmonk admin password"
listmonk_password="strongpassword"
fi
# Update Listmonk credentials
update_env_var "LISTMONK_ADMIN_USER" "$listmonk_user"
update_env_var "LISTMONK_ADMIN_PASSWORD" "$listmonk_password"
echo "Listmonk admin credentials updated."
# Flatnotes User Credentials configuration
echo -e "\n---- Flatnotes User Credentials ----"
read -p "Enter Flatnotes username [default: user]: " flatnotes_user
read -sp "Enter Flatnotes password [default: changeMe!]: " flatnotes_password
echo # Add new line after password input
if [ -z "$flatnotes_user" ]; then
echo "Using default Flatnotes username: user"
flatnotes_user="user"
fi
if [ -z "$flatnotes_password" ]; then
echo "Using default Flatnotes password"
flatnotes_password="changeMe!"
fi
# Update Flatnotes credentials
update_env_var "FLATNOTES_USERNAME" "$flatnotes_user"
update_env_var "FLATNOTES_PASSWORD" "$flatnotes_password"
echo "Flatnotes user credentials updated."
# N8N User Credentials configuration
echo -e "\n---- N8N Admin Credentials ----"
read -p "Enter N8N admin email [default: admin@example.com]: " n8n_email
read -sp "Enter N8N admin password [default: changeMe]: " n8n_password
echo # Add new line after password input
if [ -z "$n8n_email" ]; then
echo "Using default N8N admin email: admin@example.com"
n8n_email="admin@example.com"
fi
if [ -z "$n8n_password" ]; then
echo "Using default N8N admin password: changeMe"
n8n_password="changeMe"
fi
# Update N8N host and other settings
update_env_var "N8N_HOST" "n8n.$domain_name"
update_env_var "N8N_USER_EMAIL" "$n8n_email"
update_env_var "N8N_USER_PASSWORD" "$n8n_password"
update_env_var "GENERIC_TIMEZONE" "UTC"
echo "N8N admin credentials updated."
# Rocket.Chat Configuration
echo -e "\n---- Rocket.Chat Configuration ----"
read -p "Enter Rocket.Chat URL (default: https://rocket.$domain_name): " rocketchat_url
read -p "Enter Rocket.Chat port [default: 3004]: " rocketchat_port
read -p "Enable production mode for Rocket.Chat? [Y/n]: " rocketchat_production
if [ -z "$rocketchat_url" ]; then
echo "Using default Rocket.Chat URL: https://rocket.$domain_name"
rocketchat_url="https://rocket.$domain_name"
fi
if [ -z "$rocketchat_port" ]; then
echo "Using default Rocket.Chat port: 3004"
rocketchat_port="3004"
fi
rocketchat_environment="changemaker"
if [[ "$rocketchat_production" =~ ^[Yy]$ ]] || [ -z "$rocketchat_production" ]; then
echo "Enabling production mode for Rocket.Chat"
rocketchat_environment="production"
fi
# Update Rocket.Chat settings
update_env_var "ROCKETCHAT_PORT" "$rocketchat_port"
update_env_var "ROCKETCHAT_CONTAINER_PORT" "3000"
update_env_var "ROCKETCHAT_ROOT_URL" "$rocketchat_url"
update_env_var "ROCKETCHAT_DEPLOYMENT_ENVIRONMENT" "$rocketchat_environment"
echo "Rocket.Chat configuration updated."
# Cloudflare Credentials Configuration
echo -e "\n---- Cloudflare Credentials Configuration ----"
echo "Please enter your Cloudflare credentials for DNS and tunnel management."
read -p "Enter Cloudflare authentication email: " cf_auth_email
read -p "Enter Cloudflare API token: " cf_api_token
read -p "Enter Cloudflare Zone ID: " cf_zone_id
read -p "Enter Cloudflare Tunnel ID: " cf_tunnel_id
if [ -z "$cf_auth_email" ]; then
echo "Warning: Cloudflare authentication email is empty. Some features may not work correctly."
fi
if [ -z "$cf_api_token" ]; then
echo "Warning: Cloudflare API token is empty. Some features may not work correctly."
fi
if [ -z "$cf_zone_id" ]; then
echo "Warning: Cloudflare Zone ID is empty. Some features may not work correctly."
fi
if [ -z "$cf_tunnel_id" ]; then
echo "Warning: Cloudflare Tunnel ID is empty. Some features may not work correctly."
fi
# Update Cloudflare settings
update_env_var "CF_AUTH_EMAIL" "$cf_auth_email"
update_env_var "CF_API_TOKEN" "$cf_api_token"
update_env_var "CF_ZONE_ID" "$cf_zone_id"
update_env_var "CF_TUNNEL_ID" "$cf_tunnel_id"
update_env_var "CF_DOMAIN" "$domain_name"
echo "Cloudflare credentials have been updated."
echo -e "\n---- Generating Random Strong Passwords ----"
echo "Generating and updating passwords for all other services..."
# Generate and update Monica app key
monica_app_key=$(generate_base64_key 32)
update_env_var "MONICA_APP_KEY" "$monica_app_key"
# Generate and update Monica passwords
monica_db_password=$(generate_password 20)
update_env_var "MONICA_DB_PASSWORD" "$monica_db_password"
update_env_var "MONICA_MYSQL_PASSWORD" "$monica_db_password"
# Generate and update Flatnotes secret key
flatnotes_secret_key=$(generate_password 32)
update_env_var "FLATNOTES_SECRET_KEY" "$flatnotes_secret_key"
# Generate and update Gitea passwords
gitea_db_password=$(generate_password 24)
gitea_root_password=$(generate_password 24)
update_env_var "GITEA_DB_PASSWD" "$gitea_db_password"
update_env_var "GITEA_DB_ROOT_PASSWORD" "$gitea_root_password"
# Generate and update NocoDB JWT secret and database password
nocodb_jwt_secret=$(generate_password 32)
update_env_var "NOCODB_JWT_SECRET" "$nocodb_jwt_secret"
nocodb_db_password=$(generate_password 20)
update_env_var "NOCODB_DB_PASSWORD" "$nocodb_db_password"
# Generate and update n8n encryption key and default admin password
n8n_encryption_key=$(generate_password 32)
update_env_var "N8N_ENCRYPTION_KEY" "$n8n_encryption_key"
# Generate and update ConvertX JWT secret
convertx_jwt_secret=$(generate_password 48)
update_env_var "CONVERTX_JWT_SECRET" "$convertx_jwt_secret"
echo "All service passwords have been updated with secure random strings."
echo -e "\nAll settings have been configured successfully!"
echo "Your Changemaker instance is now ready with the following:"
echo "- Domain: $domain_name"
echo "- Listmonk Admin: $listmonk_user"
echo "- Flatnotes User: $flatnotes_user"
echo "- N8N Admin Email: $n8n_email"
echo "- All other service passwords have been randomized for security"
echo -e "\nNote: The randomized passwords are stored in your .env file at: $ENV_FILE"
echo -e "A backup of your original .env file was created before modifications."
# Add a new function to write the complete .env file
write_new_env_file() {
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="$ENV_FILE.backup_$timestamp"
echo "Creating final backup of the current .env file to: $backup_file"
cp "$ENV_FILE" "$backup_file"
echo "Creating new .env file with all updated settings..."
# Get all variables from the current .env file
local temp_env=$(mktemp)
grep -v "^#" "$ENV_FILE" | grep "=" > "$temp_env"
# Create the new .env file with header
cat > "$ENV_FILE.new" << EOL
# Never share this file publicly. It contains sensitive information.
# This file is used to configure various applications and services.
# Generated by Changemaker Config Wizard on $(date)
EOL
# Add all sections with their variables
echo "# Domain Configuration" >> "$ENV_FILE.new"
grep -E "^DOMAIN=|^BASE_DOMAIN=" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Listmonk Configuration" >> "$ENV_FILE.new"
grep -E "^LISTMONK_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Database Credentials" >> "$ENV_FILE.new"
grep -E "^POSTGRES_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Monica CRM Configuration" >> "$ENV_FILE.new"
grep -E "^MONICA_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# MkDocs Configuration" >> "$ENV_FILE.new"
grep -E "^USER_ID=|^GROUP_ID=|^MKDOCS_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Flatnotes Configuration" >> "$ENV_FILE.new"
grep -E "^FLATNOTES_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Gitea Configuration" >> "$ENV_FILE.new"
grep -E "^GITEA_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Apache Answer Configuration" >> "$ENV_FILE.new"
grep -E "^ANSWER_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Excalidraw Configuration" >> "$ENV_FILE.new"
grep -E "^EXCALIDRAW_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Code Server Configuration" >> "$ENV_FILE.new"
grep -E "^CODE_SERVER_|^USER_NAME=" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Cloudflare Credentials" >> "$ENV_FILE.new"
grep -E "^CF_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# NocoDB Configuration" >> "$ENV_FILE.new"
grep -E "^NOCODB_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# OpenWebUI Configuration" >> "$ENV_FILE.new"
grep -E "^OPEN_WEBUI_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# N8N Configuration" >> "$ENV_FILE.new"
grep -E "^N8N_|^GENERIC_TIMEZONE=" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# ConvertX Configuration" >> "$ENV_FILE.new"
grep -E "^CONVERTX_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
echo "# Rocket.Chat Configuration" >> "$ENV_FILE.new"
grep -E "^ROCKETCHAT_" "$temp_env" >> "$ENV_FILE.new"
echo "" >> "$ENV_FILE.new"
# Any variables that didn't fit in the above categories
echo "# Additional Configuration" >> "$ENV_FILE.new"
grep -v -E "^DOMAIN=|^BASE_DOMAIN=|^LISTMONK_|^POSTGRES_|^MONICA_|^USER_ID=|^GROUP_ID=|^MKDOCS_|^FLATNOTES_|^GITEA_|^ANSWER_|^EXCALIDRAW_|^CODE_SERVER_|^USER_NAME=|^CF_|^NOCODB_|^OPEN_WEBUI_|^N8N_|^GENERIC_TIMEZONE=|^CONVERTX_|^ROCKETCHAT_" "$temp_env" >> "$ENV_FILE.new"
# Replace the current .env with the new one
mv "$ENV_FILE.new" "$ENV_FILE"
# Clean up
rm -f "$temp_env"
echo "New .env file created and applied successfully!"
}
# Finalizing the configuration by creating a clean .env file...
echo -e "\nFinalizing the configuration by creating a clean .env file..."
write_new_env_file
# Clean up any leftover temporary backup files
rm -f "$ENV_FILE.bak_tmp"
echo -e "Temporary backup files have been cleaned up."