#! /bin/bash # Color definitions GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color # Logger functions log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } CURRENT_DIR=$(pwd) SERVICE_FILE="haraka.service" SERVICE_PATH="/etc/systemd/system/$SERVICE_FILE" LOCAL_SERVICE_PATH="$CURRENT_DIR/$SERVICE_FILE" # Load environment variables if [ -f "$CURRENT_DIR/.env" ]; then export $(cat "$CURRENT_DIR/.env" | grep -v '^#' | xargs) else log_error ".env file not found" exit 1 fi # Check if MYSQL_ADMIN_PASSWORD is set if [ -z "$MYSQL_ADMIN_PASSWORD" ]; then log_error "MYSQL_ADMIN_PASSWORD not found in .env file" exit 1 fi if [ -z "$MYSQL_ADMIN_USER" ]; then log_error "MYSQL_ADMIN_USER not found in .env file" exit 1 fi sudo_cmd() { echo "$SUDO_PASSWORD" | sudo -S "$@" 2>/dev/null } # Test sudo access if ! sudo_cmd true; then echo "Error: Invalid sudo password" exit 1 fi # Database configuration DB_NAME="tempmail" DB_USER="tempmail" DB_PASS=$(openssl rand -base64 12) # Generate random password # Check if mysql-server is installed if ! command -v mysql &> /dev/null; then log_warn "MySQL Server not found. Installing..." sudo_cmd apt-get update >> /dev/null 2>&1 sudo_cmd apt-get install -y mysql-server >> /dev/null 2>&1 else log_info "MySQL Server is already installed" fi # Wait for MySQL to be ready log_info "Waiting for MySQL to be ready..." while ! mysqladmin ping -h "localhost" -u admin -p"${MYSQL_ADMIN_PASSWORD}" --silent; do sleep 1 done # Create database and user log_info "Setting up MySQL database and user..." mysql -u admin -p"${MYSQL_ADMIN_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME};" # Check if user exists USER_EXISTS=$(mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -s -N -e "SELECT COUNT(*) FROM mysql.user WHERE User = '${DB_USER}' AND Host = 'localhost';") if [ "$USER_EXISTS" -eq 0 ]; then log_info "Creating new database user..." mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';" mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';" mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "FLUSH PRIVILEGES;" # Update database config file with new values log_info "Updating database configuration..." cp "$CURRENT_DIR/src/config/database-example.js" "$CURRENT_DIR/src/config/database.js" CONFIG_FILE="$CURRENT_DIR/src/config/database.js" sed -i "s/database: \"\"/database: '${DB_NAME}'/" "$CONFIG_FILE" sed -i "s/user: \"\"/user: '${DB_USER}'/" "$CONFIG_FILE" sed -i "s/password: \"\"/password: '${DB_PASS}'/" "$CONFIG_FILE" log_info "Database password has been updated in the configuration file" else log_warn "Database user already exists. Skipping user creation and configuration update." fi # Create group and user log_info "Creating group and user..." sudo_cmd groupadd smtp 2>/dev/null || true sudo_cmd useradd -r -g smtp smtp 2>/dev/null || true # Create required directories log_info "Creating required directories..." sudo_cmd mkdir -p /var/spool/haraka /var/log/haraka sudo_cmd chown -R smtp:smtp /var/spool/haraka /var/log/haraka # Set permissions log_info "Setting permissions..." sudo_cmd chmod 755 /var/spool/haraka sudo_cmd chmod 644 /var/log/haraka # Install Haraka log_info "Installing Haraka..." if ! command -v haraka &> /dev/null; then npm install -g Haraka else log_warn "Haraka is already installed" fi # Check if service file exists and handle accordingly log_info "Checking if service file exists..." if [ -f "$SERVICE_PATH" ]; then # Calculate checksums REMOTE_CHECKSUM=$(sha1sum "$SERVICE_PATH" | awk '{print $1}') LOCAL_CHECKSUM=$(sha1sum "$LOCAL_SERVICE_PATH" | awk '{print $1}') if [ "$REMOTE_CHECKSUM" != "$LOCAL_CHECKSUM" ]; then log_warn "Service file differs from local version. Updating..." sudo_cmd cp "$LOCAL_SERVICE_PATH" "$SERVICE_PATH" sudo_cmd systemctl daemon-reload sudo_cmd systemctl enable haraka sudo_cmd systemctl restart haraka else log_info "Service file is up to date" fi else log_info "Service file not found. Installing..." sudo_cmd cp "$LOCAL_SERVICE_PATH" "$SERVICE_PATH" sudo_cmd systemctl daemon-reload log_info "Enabling and starting Haraka..." sudo_cmd systemctl enable haraka fi # Install Haraka plugins log_info "Installing Haraka plugins..." mkdir -p "$CURRENT_DIR/src/email_server/plugins/queue" rm -f "$CURRENT_DIR/src/email_server/plugins/queue/store_message.js" ln -s "$CURRENT_DIR/src/haraka-plugins/queue/store_message.js" "$CURRENT_DIR/src/email_server/plugins/queue/store_message.js" log_info "Installing dependencies..." npm install >> /dev/null 2>&1 log_info "Running migrations..." npx knex migrate:latest # CRON_FILE="$CURRENT_DIR/.cron" # echo "" > "$CRON_FILE" # echo "0 * * * * $CURRENT_DIR/scripts/delete_messages_24h.sh >> /var/log/temp_mail/cleanup.log 2>&1" >> "$CRON_FILE" # echo "0 0 * * * $CURRENT_DIR/scripts/delete_emails_14d.sh >> /var/log/temp_mail/cleanup.log 2>&1" >> "$CRON_FILE" # TEMP_CRON="/tmp/temp_cron" # mkdir -p /var/log/temp_mail # # Check if .cron file exists # if [ ! -f "$CRON_FILE" ]; then # log_error "Cron file not found at $CRON_FILE" # exit 1 # fi # # Function to normalize cron entry (remove extra spaces) # normalize_cron() { # echo "$1" | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//' -e 's/[ \t]\+/ /g' # } # # Function to check if a cron job exists # check_cron_job() { # local cron_entry="$1" # local normalized_entry=$(normalize_cron "$cron_entry") # # Get current user's crontab # crontab -l > "$TEMP_CRON" 2>/dev/null # # Check if the normalized entry exists in current crontab # if grep -Fq "$normalized_entry" "$TEMP_CRON"; then # return 0 # Found # else # return 1 # Not found # fi # } # # Function to install cron jobs # install_cron_jobs() { # log_info "Installing cron jobs..." # # Get current crontab # crontab -l > "$TEMP_CRON" 2>/dev/null # # Read each line from .cron file # while IFS= read -r line || [ -n "$line" ]; do # # Skip comments and empty lines # [[ $line =~ ^#.*$ ]] || [ -z "$line" ] && continue # normalized_line=$(normalize_cron "$line") # if ! grep -Fq "$normalized_line" "$TEMP_CRON"; then # log_warn "Cron job not found, adding: $normalized_line" # echo "$normalized_line" >> "$TEMP_CRON" # else # log_info "Cron job already exists: $normalized_line" # fi # done < "$CRON_FILE" # # Install new crontab # crontab "$TEMP_CRON" # # Clean up # rm -f "$TEMP_CRON" # } # # Main execution # log_info "Checking cron jobs..." # # Read .cron file and check each entry # missing_jobs=0 # while IFS= read -r line || [ -n "$line" ]; do # # Skip comments and empty lines # [[ $line =~ ^#.*$ ]] || [ -z "$line" ] && continue # if ! check_cron_job "$line"; then # log_warn "Missing cron job: $line" # missing_jobs=$((missing_jobs + 1)) # else # log_info "Found cron job: $line" # fi # done < "$CRON_FILE" # # If any jobs are missing, offer to install them # if [ $missing_jobs -gt 0 ]; then # log_warn "Found $missing_jobs missing cron job(s)" # install_cron_jobs # log_info "Cron jobs have been updated" # else # log_info "All cron jobs are up to date" # fi log_info "Installation complete!" log_info "You can now start the email server with: sudo systemctl start haraka"