HEX
Server: nginx/1.29.3
System: Linux 11979.bigscoots-wpo.com 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64
User: nginx (1068)
PHP: 7.4.33
Disabled: exec,system,passthru,shell_exec,proc_open,proc_close,popen,show_source,cmd# Do not modify this line # 1684243876
Upload Files
File: //bigscoots/wpo/cloudflare/cfent_init.sh
#!/bin/bash

source /bigscoots/includes/common.sh
source /root/.bigscoots/.cf

ENTZONE=c2d79b78db1f915729e6a48f8bd6b0c3
CFAPIURL=https://api.cloudflare.com/client/v4

# Usage information
usage() {
    echo "Usage: $0 --domain DOMAIN --ip IP [--email EMAIL] [--apikey APIKEY] [--zoneid ZONEID] [--run]"
    echo "Mandatory options:"
    echo "  --domain DOMAIN    Domain name to update DNS records for"
    echo "  --ip IP            IP address to set for the DNS records"
    echo "Optional options:"
    echo "  --email EMAIL      Cloudflare email address"
    echo "  --apikey APIKEY    Cloudflare API key"
    echo "  --zoneid ZONEID    Cloudflare zone ID"
    echo "Flags:"
    echo "  --run              Run the script in the current session (used internally)"
    exit 0
}

function status_check () {
    # Initialize JSON response
    init_json_response

    # Get the Cloudflare custom hostname ID
    CFAPICHNAMEID=$(cat "/root/cfplugin/${DOMAIN}.step2.api" | jq -r '.result.id')

    # Fetch the custom hostname details
    RESPONSE=$(curl -s -X GET \
      --url "${CFAPIURL}/zones/${ENTZONE}/custom_hostnames/${CFAPICHNAMEID}" \
      --header 'Content-Type: application/json' \
      --header "Authorization: Bearer ${CFAPITOKEN}")

    # Extract required fields
    SSL_STATUS=$(echo "$RESPONSE" | jq -r '.result.ssl.status // "unknown"')
    HOSTNAME_STATUS=$(echo "$RESPONSE" | jq -r '.result.status // "unknown"')
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Build the result JSON
    RESULT_JSON=$(jq -n \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg domain "$DOMAIN" \
        --arg ssl_status "$SSL_STATUS" \
        --arg hostname_status "$HOSTNAME_STATUS" \
        '{
            bs_site_id: $bs_site_id,
            domain: $domain,
            ssl_status: $ssl_status,
            hostname_status: $hostname_status
        }')

    # Set the JSON response
    set_json_result "$RESULT_JSON"
    set_json_success

    # Print the JSON response
    print_json_response
}

# Parse command line arguments
RUN=0
ZONEID_ARG=""
while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
        --domain)
            DOMAIN="$2"
            shift
            shift
            ;;
        --ip)
            IP="$2"
            shift
            shift
            ;;
        --email)
            DOMAIN_CF_EMAIL="$2"
            shift
            shift
            ;;
        --apikey)
            DOMAIN_CF_APIKEY="$2"
            shift
            shift
            ;;
        --zoneid)
            DOMAIN_CF_ZONEID="$2"
            ZONEID_ARG="--zoneid \"$DOMAIN_CF_ZONEID\""
            shift
            shift
            ;;
        --run)
            RUN=1
            shift
            ;;
        --status)
            status_check
            exit 0
            ;;
        *) 
            usage
            ;;
    esac
done

# Check that mandatory options are present
if [ -z "$DOMAIN" ] || [ -z "$IP" ]; then
    usage
fi

function GEN_PKEY () {
    # Generate the .info file with data from the master server
    if [ ! -f /root/cfplugin/"${DOMAIN}".info ]; then
        ssh "${SSH_OPTIONS[@]}" -p 2222 [email protected] "bash /var/www/main.bigscoots.com/create_master.sh ${DOMAIN} ${ENTZONE} ${IP}" >> /root/cfplugin/"${DOMAIN}".info
    fi

    # Read the JSON data from the .info file
    JSON_PAYLOAD=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq --arg hash "$HASH" '
        . | to_entries | 
        map(if .key == "bs_site_id" then . , {"key": "hash", "value": $hash} else . end) | 
        from_entries
    ')

    # Check all keys for non-empty, non-null, and non-"null" values
    IS_SUCCESS=$(echo "$JSON_PAYLOAD" | jq '
        . as $object | 
        reduce keys[] as $key (true; . and ($object[$key] != null and $object[$key] != "" and $object[$key] != "null"))
    ')

    # Append the success status to the JSON
    JSON_PAYLOAD=$(echo "$JSON_PAYLOAD" | jq --argjson success "$IS_SUCCESS" '. + {success: $success}')

    # Send the JSON data to the API endpoint
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "${JSON_PAYLOAD}")

    # Output the JSON payload and API response (optional, for debugging)
    echo "$JSON_PAYLOAD"
    echo "API Response: ${RESPONSE}"
}

function DEPLOY_PKEY () {
    # Extract the bs_site_id from the .info file
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    if [ -n "$BS_SITE_ID" ] && [ "$BS_SITE_ID" != "null" ]; then
        STATUS=true
    else
        STATUS=false
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "deploy pkey" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg status "$STATUS" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "success": $status
        }')

    echo "$JSON_PAYLOAD"

    # Send the JSON payload to the API endpoint
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output the API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}

function FINALSTEPS () {
    BS_MASTER_KEY=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_master_key')
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Execute the remote SSH command
    WPO_SSL_STATUS=$(ssh "${SSH_OPTIONS[@]}" -p 2222 "${IP}" "bash /bigscoots/wpo/cloudflare/fujames.sh ${DOMAIN} ${BS_MASTER_KEY} ${BS_SITE_ID}")
    SSH_EXIT_CODE=$?

    export WPO_SSL_STATUS
    # Determine success status based on the SSH exit code
    if [[ $SSH_EXIT_CODE -eq 0 ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    # Extract bs_site_id from the .info file
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "wpo deployment and ssl" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg domain "$DOMAIN" \
        --arg ip "$IP" \
        --arg success "$STATUS" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "ip": $ip,
            "success": ($success | test("true"))
        }')

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    echo "$JSON_PAYLOAD"

    # Output API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}	

function GATHERCFAPI () {
    # Check if CFAPI already exists
    if grep -q CFAPI /root/cfplugin/"${DOMAIN}".info; then
        send_slack_alert "#cloudflare" ":warning:" "Function: \`GATHERCFAPI\`" "$hostname" "CFAPI already exists in /root/cfplugin/${DOMAIN}.info\nIf this info is incorrect or incomplete then remove CFAPI lines and rerun this command."
    else
        # Generate CFAPI info and append it to the .info file
        ssh "${SSH_OPTIONS[@]}" -p 2222 "${IP}" "bash /bigscoots/wpo/cloudflare/fujames.sh ${DOMAIN} CFAPI" >> /root/cfplugin/"${DOMAIN}".info
    fi

    # Extract bs_site_id from the JSON block
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Extract CFAPI values from the text outside of the JSON
    CFAPI_DOMAIN=$(grep 'CFAPI Domain' /root/cfplugin/"${DOMAIN}".info | awk '{print $3}')
    CFAPI_SERVERIP=$(grep 'CFAPI Server IP' /root/cfplugin/"${DOMAIN}".info | awk '{print $4}')
    CFAPI_CANONICALDOMAIN=$(grep 'CFAPI Canonical Domain' /root/cfplugin/"${DOMAIN}".info | awk '{print $4}')
    CFAPI_CUSTOMHOSTNAME=$(grep 'CFAPI Custom Hostname' /root/cfplugin/"${DOMAIN}".info | awk '{print $4}')

    # Determine the status based on whether all CFAPI variables were set
    if [[ -n "$CFAPI_DOMAIN" && -n "$CFAPI_SERVERIP" && -n "$CFAPI_CANONICALDOMAIN" && -n "$CFAPI_CUSTOMHOSTNAME" ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "gather cfapi" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg cfapi_domain "$CFAPI_DOMAIN" \
        --arg cfapi_serverip "$CFAPI_SERVERIP" \
        --arg cfapi_canonicaldomain "$CFAPI_CANONICALDOMAIN" \
        --arg cfapi_customhostname "$CFAPI_CUSTOMHOSTNAME" \
        --arg success "$STATUS" \
        '{
            step: $step,
            bs_site_id: $bs_site_id,
            hash: $hash,
            cfapi: {
                domain: $cfapi_domain,
                server_ip: $cfapi_serverip,
                canonical_domain: $cfapi_canonicaldomain,
                custom_hostname: $cfapi_customhostname
            },
            success: ($success | test("true"))
        }')

    echo "$JSON_PAYLOAD"

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output the API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}

function ADDDNSCFAPI () {	
	if [[ -f "/root/cfplugin/${DOMAIN}.step1.api" ]]; then
	    # File exists, check the .success field
	    SUCCESS=$(jq -r '.success' < "/root/cfplugin/${DOMAIN}.step1.api")
	else
	    # File does not exist, set SUCCESS to "false" to trigger curl
	    SUCCESS="false"
	fi

	# Run curl request if success is false
	if [[ "$SUCCESS" != "true" ]]; then
	    curl -s -X POST "${CFAPIURL}/zones/${ENTZONE}/dns_records" \
	        -H "Authorization: Bearer ${CFAPITOKEN}" \
	        -H "Content-Type: application/json" \
	        --data '{"type":"A","name":"'"$CFAPI_DOMAIN"'","content":"'"$CFAPI_SERVERIP"'","ttl":120,"priority":10,"proxied":true}' \
	        -o "/root/cfplugin/${DOMAIN}.step1.api"
	fi

    # Extract response data
    API_RESPONSE=$(cat /root/cfplugin/${DOMAIN}.step1.api)
    SUCCESS=$(echo "$API_RESPONSE" | jq -r '.success')
    ID=$(echo "$API_RESPONSE" | jq -r '.result.id')
    CONTENT=$(echo "$API_RESPONSE" | jq -r '.result.content')

    # Convert Cloudflare success to JSON success: true/false
    if [[ "$SUCCESS" == "true" ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    # Extract bs_site_id from the .info file
	BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "add custom hostname dns record" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg success "$STATUS" \
        --arg id "$ID" \
        --arg content "$CONTENT" \
        '{
            step: $step,
            bs_site_id: $bs_site_id,
            hash: $hash,
            success: ($success | test("true")),
            record: {
                id: $id,
                content: $content
            }
        }')

    echo "$JSON_PAYLOAD"

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}


function ADDCHNAMECFAPI () {
    if [[ -f "/root/cfplugin/${DOMAIN}.step2.api" ]]; then
        SUCCESS=$(jq -r '.success' < "/root/cfplugin/${DOMAIN}.step2.api")
    else
        SUCCESS="false"
    fi

    if [[ "$SUCCESS" != "true" ]]; then
        curl -s -X POST "${CFAPIURL}/zones/${ENTZONE}/custom_hostnames" \
            -H "Authorization: Bearer ${CFAPITOKEN}" \
            -H "Content-Type: application/json" \
            --data '{
                "hostname": "'"$CFAPI_CANONICALDOMAIN"'",
                "ssl": {
                    "bundle_method": "ubiquitous",
                    "certificate_authority": "lets_encrypt",
                    "method": "http",
                    "settings": {
                        "early_hints": "on",
                        "http2": "on",
                        "http3": "on",
                        "min_tls_version": "1.2",
                        "tls_1_3": "on"
                    },
                    "type": "dv",
                    "wildcard": false
                }
            }' \
            -o "/root/cfplugin/${DOMAIN}.step2.api"
    fi

    # Extract API response
    API_RESPONSE=$(cat /root/cfplugin/${DOMAIN}.step2.api)
    SUCCESS=$(echo "$API_RESPONSE" | jq -r '.success')
    ID=$(echo "$API_RESPONSE" | jq -r '.result.id')
    OWNERSHIP_HTTP_URL=$(echo "$API_RESPONSE" | jq -r '.result.ownership_verification_http.http_url')
    OWNERSHIP_HTTP_BODY=$(echo "$API_RESPONSE" | jq -r '.result.ownership_verification_http.http_body')

    if [[ "$SUCCESS" == "true" ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    JSON_PAYLOAD=$(jq -n \
        --arg step "add custom hostname" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg success "$STATUS" \
        --arg id "$ID" \
        --arg ownership_http_url "$OWNERSHIP_HTTP_URL" \
        --arg ownership_http_body "$OWNERSHIP_HTTP_BODY" \
        '{
            step: $step,
            bs_site_id: $bs_site_id,
            hash: $hash,
            success: ($success | test("true")),
            result: {
                id: $id,
                ownership_verification_http: {
                    http_url: $ownership_http_url,
                    http_body: $ownership_http_body
                }
            }
        }')

    echo "$JSON_PAYLOAD"

    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    echo "API Response: ${RESPONSE}"
}

function MDFYCHNAMECFAPI () {
	CFAPICHNAMEID=$(cat /root/cfplugin/${DOMAIN}.step2.api | jq -r '.result.id')

	curl -s -X PATCH "${CFAPIURL}/zones/${ENTZONE}/custom_hostnames/${CFAPICHNAMEID}" \
     -H "Authorization: Bearer ${CFAPITOKEN}" \
     -H "Content-Type: application/json" \
     --data '{"custom_origin_server":"'"$CFAPI_CUSTOMHOSTNAME"'"}' \
     -o /root/cfplugin/${DOMAIN}.step3.api
}

function GETCHNAMEINFO () {
	CFAPICHNAMEID=$(cat /root/cfplugin/${DOMAIN}.step2.api | jq -r '.result.id')

    curl -s -X PATCH "${CFAPIURL}/zones/${ENTZONE}/custom_hostnames/${CFAPICHNAMEID}" \
     -H "Authorization: Bearer ${CFAPITOKEN}" \
     -H "Content-Type: application/json" \
     --data '{"ssl":{"method":"http","type":"dv","settings":{"min_tls_version":"1.2"}}}' \
	  -o /root/cfplugin/${DOMAIN}.step3.api
}

function VRFYCFAPI () {
    MAX_RETRIES=100
    RETRY_COUNT=0
    SUCCESS="false"

    while true; do
        GETCHNAMEINFO

        SSL_STATUS=$(jq -r '.result.ssl.status' < /root/cfplugin/"${DOMAIN}".step3.api)
        SSL_HTTP_URL=$(jq -r '.result.ssl.validation_records[0].http_url // empty' < /root/cfplugin/"${DOMAIN}".step3.api)
        SSL_HTTP_BODY=$(jq -r '.result.ssl.validation_records[0].http_body // empty' < /root/cfplugin/"${DOMAIN}".step3.api)

        if [[ "$SSL_STATUS" == "active" || ( -n "$SSL_HTTP_URL" && -n "$SSL_HTTP_BODY" ) ]]; then
            SUCCESS="true"
            break
        fi

        ((RETRY_COUNT++))
        if [[ $RETRY_COUNT -ge $MAX_RETRIES ]]; then
            echo "Maximum retries reached. Continuing script without valid SSL verification."
            break
        fi

        sleep 5
    done

    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    if [[ ${CFAPI_CANONICALDOMAIN} = www* ]]; then
        CANONICAL=www
    else
        CANONICAL=nonwww
    fi

    JSON_PAYLOAD=$(jq -n \
        --arg step "obtain SSL verification records" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg domain "$DOMAIN" \
        --arg ssl_http_url "$SSL_HTTP_URL" \
        --arg ssl_http_body "$SSL_HTTP_BODY" \
        --arg ssl_status "$SSL_STATUS" \
        --arg success "$SUCCESS" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "ssl_verification": {
                "http_url": $ssl_http_url,
                "http_body": $ssl_http_body,
                "status": $ssl_status
            },
            "success": ($success | test("true"))
        }')

    echo "$JSON_PAYLOAD"

    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    echo "API Response: ${RESPONSE}"

    # Updated Slack message - no TXT records needed, HTTP challenge is automatic
    bash /bigscoots/general/slack.sh "#cloudflare" "\n \n \n \
    :zap:*Cloudflare Enterprise Setup*:zap: \
    \n \
    Domain: \`${DOMAIN}\` on server IP: \`${IP}\` \n \
    \n \
    In WPO Admin, set Cloudflare Plan to purchased *Tier 1,2,3*.\n \
    \n \
    Remove the ORANGE CLOUD from record: \`${CFAPI_CANONICALDOMAIN}\` \n \
    Ensure the NON Canonical Domain is pointed with an A Record, Orange Cloud. Sometimes its a CNAME which will cause it to fail. \n \
    \n \
    SSL verification is via *HTTP challenge* (no DNS records needed). \n \
    HTTP URL: \`${SSL_HTTP_URL}\` \n \
    SSL Status: \`${SSL_STATUS}\` \n \
    SSH into \`${IP}\` and force non Canonical Domain to \`${CFAPI_CANONICALDOMAIN}\` \n \
    \`\`\`bash /bigscoots/wpo/manage/set.sh canonical ${DOMAIN} ${CANONICAL}\`\`\`
    Wait 15 minutes then you can change the \`${CFAPI_CANONICALDOMAIN}\` record to a CNAME and point to \`enterprise.tier1.bigscoots.com.\` with a GREY cloud."
}

function HANDLE_TXT_RECORD () {
    local STEP=$1
    local TXT_NAME=$2
    local TXT_VALUE=$3

    # Add TXT record and capture response
    ADD_TXT_RESPONSE=$(ADD_TXT_RECORD "$TXT_NAME" "$TXT_VALUE")
    ADD_TXT_SUCCESS=$(echo "$ADD_TXT_RESPONSE" | jq -r '.success')
    ADD_TXT_ERRORS=$(echo "$ADD_TXT_RESPONSE" | jq -c '.errors')
    ADD_TXT_MESSAGES=$(echo "$ADD_TXT_RESPONSE" | jq -c '.messages')

    # Determine success status
    if [[ "$ADD_TXT_SUCCESS" == "true" ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "$STEP" \
        --arg domain "$DOMAIN" \
        --arg txt_name "$TXT_NAME" \
        --arg txt_value "$TXT_VALUE" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg success "$STATUS" \
        --arg errors "$ADD_TXT_ERRORS" \
        --arg messages "$ADD_TXT_MESSAGES" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "txt_record": {
                "name": $txt_name,
                "value": $txt_value
            },
            "success": ($success | test("true")),
            "errors": ($errors | fromjson),
            "messages": ($messages | fromjson)
        }')

    echo "$JSON_PAYLOAD"

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}

# Function to add TXT record
ADD_TXT_RECORD() {
  local NAME=$1
  local CONTENT=$2
  local RECORD_TYPE=TXT
  # echo "Adding TXT record with value: $NAME $CONTENT"
  curl -s -X POST "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records" \
       -H "Content-Type: application/json" \
       -H "X-Auth-Key: $DOMAIN_CF_APIKEY" \
       -H "X-Auth-Email: $DOMAIN_CF_EMAIL" \
       --data "{\"type\":\"$RECORD_TYPE\",\"name\":\"$NAME\",\"content\":\"$CONTENT\",\"ttl\":1,\"proxied\":false}" \
       | jq '{success: .success, errors: .errors, messages: .messages}'
}

function UPDATE_DNS_CFENT_CNAME () {
    # echo "🔄 Updating Cloudflare Canonical DNS Record for $CFAPI_CANONICALDOMAIN..."

    # Update the DNS record to set it as a CNAME
    CF_UPDATE_RESPONSE=$(curl --silent --location --request PUT "https://api.cloudflare.com/client/v4/zones/$DOMAIN_CF_ZONEID/dns_records/$DNS_RECORD_ID" \
        -H "Content-Type: application/json" \
        -H "X-Auth-Key: $DOMAIN_CF_APIKEY" \
        -H "X-Auth-Email: $DOMAIN_CF_EMAIL" \
        --data "{\"type\":\"CNAME\",\"name\":\"$CFAPI_CANONICALDOMAIN\",\"content\":\"enterprise.tier1.bigscoots.com\",\"proxied\":false}")

    # Extract relevant fields from the response
    CF_UPDATE_SUCCESS=$(echo "$CF_UPDATE_RESPONSE" | jq -r '.success')
    CF_UPDATE_ERRORS=$(echo "$CF_UPDATE_RESPONSE" | jq -c '.errors')
    CF_UPDATE_MESSAGES=$(echo "$CF_UPDATE_RESPONSE" | jq -c '.messages')

    # Determine status
    if [[ "$CF_UPDATE_SUCCESS" == "true" ]]; then
        STATUS="true"
        # echo "✅ Cloudflare DNS record successfully updated to CNAME."
    else
        STATUS="false"
        # echo "❌ Cloudflare DNS update failed."
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "change cname on canonical dns" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg canonical_domain "$CFAPI_CANONICALDOMAIN" \
        --arg success "$STATUS" \
        --arg errors "$CF_UPDATE_ERRORS" \
        --arg messages "$CF_UPDATE_MESSAGES" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "canonical_domain": $canonical_domain,
            "success": ($success | test("true")),
            "errors": $errors,
            "messages": ($messages | fromjson)
        }')

    echo "$JSON_PAYLOAD"

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output API response (optional, for debugging)
    echo "🚀 API Response: ${RESPONSE}"
}

function GRAY_CLOUD_DOMAIN () {
    # Extract bs_site_id from the .info file
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # Check if SSL_STATUS is success
    if [[ "$WPO_SSL_STATUS" != success ]]; then
        # SSL is not successfully set; skip and set error messages
        GRAY_CLOUD_SUCCESS="false"
        GRAY_CLOUD_ERRORS="$DOMAIN does not have a signed SSL on the server unable to gray-cloud"
        GRAY_CLOUD_MESSAGES="[]"
    else
        # SSL is successfully set; proceed with gray-clouding
        # Get the DNS record ID for the canonical domain
        DNS_RECORD_ID=$(GET_DNS_RECORD_ID)

        # Update the DNS record to gray-cloud it
        GRAY_CLOUD_RESPONSE=$(curl --silent --location --request PUT "https://api.cloudflare.com/client/v4/zones/$DOMAIN_CF_ZONEID/dns_records/$DNS_RECORD_ID" \
            -H "Content-Type: application/json" \
            -H "X-Auth-Key: $DOMAIN_CF_APIKEY" \
            -H "X-Auth-Email: $DOMAIN_CF_EMAIL" \
            --data "{\"content\":\"$IP\",\"name\":\"$CFAPI_CANONICALDOMAIN\",\"proxied\":false,\"type\":\"A\"}")

        # Extract relevant fields from the response
        GRAY_CLOUD_SUCCESS=$(echo "$GRAY_CLOUD_RESPONSE" | jq -r '.success')
        GRAY_CLOUD_ERRORS=$(echo "$GRAY_CLOUD_RESPONSE" | jq -c '.errors')
        GRAY_CLOUD_MESSAGES=$(echo "$GRAY_CLOUD_RESPONSE" | jq -c '.messages')
    fi

    # Determine status
    if [[ "$GRAY_CLOUD_SUCCESS" == "true" ]]; then
        STATUS="true"
    else
        STATUS="false"
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "gray cloud domain" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg domain "$DOMAIN" \
        --arg ip "$IP" \
        --arg success "$STATUS" \
        --arg errors "$GRAY_CLOUD_ERRORS" \
        --arg messages "$GRAY_CLOUD_MESSAGES" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "ip": $ip,
            "success": ($success | test("true")),
            "errors": $errors,
            "messages": ($messages | fromjson)
        }')

    echo "$JSON_PAYLOAD"

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    # Output API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}

GET_ZONE_ID () {
    curl -s -X GET "${CFAPIURL}/zones?name=$DOMAIN" \
        -H "X-Auth-Email: $DOMAIN_CF_EMAIL" \
        -H "X-Auth-Key: $DOMAIN_CF_APIKEY" \
        -H "Content-Type: application/json" | jq -r '.result[0].id'
}

function CHK_CF_CUSTOM_HOSTNAME_STATUS () {
    MAX_RETRIES=100  # Maximum retries (100 attempts)
    RETRY_COUNT=0
    SUCCESS="false"  # Default to false

    while true; do
        # Fetch the latest custom hostname info
        GETCHNAMEINFO

        # Extract SSL status and result status
        SSL_STATUS=$(jq -r '.result.ssl.status' < /root/cfplugin/"${DOMAIN}".step3.api)
        RESULT_STATUS=$(jq -r '.result.status' < /root/cfplugin/"${DOMAIN}".step3.api)

        # Debugging output (optional, remove if not needed)
        echo "Attempt: $((RETRY_COUNT + 1)) | SSL Status: $SSL_STATUS | Result Status: $RESULT_STATUS"

        # Check if both statuses are "active"
        if [[ "$SSL_STATUS" == "active" && "$RESULT_STATUS" == "active" ]]; then
            SUCCESS="true"
            echo "✅ Custom hostname SSL and result status are active!"
            break  # Exit the loop when both conditions are met
        fi

        # Increment retry count and check the limit
        ((RETRY_COUNT++))
        if [[ $RETRY_COUNT -ge $MAX_RETRIES ]]; then
            echo "❌ Maximum retries reached. SSL or result status not active. Continuing script."
            break
        fi

        # Wait 10 seconds before the next check
        sleep 10
    done
}

function UPDATE_DNS_RECORD () {
    # Fetch the DNS record details for the canonical domain
    response=$(curl --silent --location "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records?name=$CFAPI_CANONICALDOMAIN" \
        --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
        --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
        --header 'Content-Type: application/json')

    # Extract record ID and type
    record_id=$(echo "$response" | jq -r '.result[0].id')
    record_type=$(echo "$response" | jq -r '.result[0].type')

    # Extract bs_site_id from the .info file
    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    # If the record is a CNAME, change it to an A record
    if [ "$record_type" == "CNAME" ]; then
        # Delete the existing CNAME record
        delete_response=$(curl --silent --location --request DELETE "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records/$record_id" \
            --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
            --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
            --header 'Content-Type: application/json')

        delete_success=$(echo "$delete_response" | jq -r '.success')
        delete_errors=$(echo "$delete_response" | jq -c '.errors')

        # If deletion was successful, create a new A record
        if [[ "$delete_success" == "true" ]]; then
            create_response=$(curl --silent --location --request POST "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records" \
                --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
                --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
                --header 'Content-Type: application/json' \
                --data '{
                  "type": "A",
                  "name": "'"$CFAPI_CANONICALDOMAIN"'",
                  "content": "'"$IP"'",
                  "ttl": 120,
                  "proxied": false
                }')

            create_success=$(echo "$create_response" | jq -r '.success')
            create_errors=$(echo "$create_response" | jq -c '.errors')

            # Determine overall success status
            if [[ "$create_success" == "true" ]]; then
                STATUS="true"
            else
                STATUS="false"
            fi
        else
            # Failed to delete the CNAME record
            STATUS="false"
            create_errors="[]"
        fi
    else
        # Record is not a CNAME, no action needed
        STATUS="true"
        delete_errors="[]"
        create_errors="[]"
    fi

    # Create JSON payload
    JSON_PAYLOAD=$(jq -n \
        --arg step "update dns record" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg domain "$DOMAIN" \
        --arg canonical_domain "$CFAPI_CANONICALDOMAIN" \
        --arg ip "$IP" \
        --arg status "$STATUS" \
        --arg delete_errors "$delete_errors" \
        --arg create_errors "$create_errors" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "canonical_domain": $canonical_domain,
            "ip": $ip,
            "success": ($status | test("true")),
            "delete_errors": ($delete_errors | fromjson),
            "create_errors": ($create_errors | fromjson)
        }')

    # Send JSON payload to the API
    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    echo "$JSON_PAYLOAD"

    # Output API response (optional, for debugging)
    echo "API Response: ${RESPONSE}"
}

function FIX_NONCANONICAL_DNS () {
    if [[ "$CFAPI_CANONICALDOMAIN" == www.* ]]; then
        NONCANONICALDOMAIN="${CFAPI_CANONICALDOMAIN#www.}"
    else
        NONCANONICALDOMAIN="www.${CFAPI_CANONICALDOMAIN}"
    fi

    NC_RESPONSE=$(curl --silent --location \
        "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records?name=$NONCANONICALDOMAIN" \
        --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
        --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
        --header 'Content-Type: application/json')

    NC_RECORD_ID=$(echo "$NC_RESPONSE" | jq -r '.result[0].id')
    NC_RECORD_TYPE=$(echo "$NC_RESPONSE" | jq -r '.result[0].type')

    BS_SITE_ID=$(sed '/^{/,/^}/!d' /root/cfplugin/"${DOMAIN}".info | jq -r '.bs_site_id')

    if [[ "$NC_RECORD_TYPE" == "CNAME" ]]; then
        DELETE_RESPONSE=$(curl --silent --location --request DELETE \
            "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records/$NC_RECORD_ID" \
            --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
            --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
            --header 'Content-Type: application/json')

        DELETE_SUCCESS=$(echo "$DELETE_RESPONSE" | jq -r '.success')

        if [[ "$DELETE_SUCCESS" == "true" ]]; then
            CREATE_RESPONSE=$(curl --silent --location --request POST \
                "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records" \
                --header "X-Auth-Email: $DOMAIN_CF_EMAIL" \
                --header "X-Auth-Key: $DOMAIN_CF_APIKEY" \
                --header 'Content-Type: application/json' \
                --data '{
                    "type": "A",
                    "name": "'"$NONCANONICALDOMAIN"'",
                    "content": "'"$IP"'",
                    "ttl": 120,
                    "proxied": true
                }')

            CREATE_SUCCESS=$(echo "$CREATE_RESPONSE" | jq -r '.success')
            CREATE_ERRORS=$(echo "$CREATE_RESPONSE" | jq -c '.errors')

            if [[ "$CREATE_SUCCESS" == "true" ]]; then
                STATUS="true"
            else
                STATUS="false"
            fi
        else
            STATUS="false"
            CREATE_ERRORS="[]"
        fi
    else
        STATUS="true"
        CREATE_ERRORS="[]"
    fi

    JSON_PAYLOAD=$(jq -n \
        --arg step "fix non-canonical dns record" \
        --arg bs_site_id "$BS_SITE_ID" \
        --arg hash "$HASH" \
        --arg domain "$DOMAIN" \
        --arg noncanonicaldomain "$NONCANONICALDOMAIN" \
        --arg record_type "$NC_RECORD_TYPE" \
        --arg ip "$IP" \
        --arg success "$STATUS" \
        --arg create_errors "$CREATE_ERRORS" \
        '{
            "step": $step,
            "bs_site_id": $bs_site_id,
            "hash": $hash,
            "domain": $domain,
            "noncanonical_domain": $noncanonicaldomain,
            "original_record_type": $record_type,
            "ip": $ip,
            "success": ($success | test("true")),
            "create_errors": ($create_errors | fromjson)
        }')

    echo "$JSON_PAYLOAD"

    RESPONSE=$(curl -s -X POST https://n8n.bigscoots.dev/webhook/wpo/cf-ent-setup \
        -H "Content-Type: application/json" \
        -d "$JSON_PAYLOAD")

    echo "API Response: ${RESPONSE}"
}

function GET_DNS_RECORD_ID() {
  curl --silent --location "${CFAPIURL}/zones/$DOMAIN_CF_ZONEID/dns_records?name=$CFAPI_CANONICALDOMAIN" \
       -H "Content-Type: application/json" \
       -H "X-Auth-Key: $DOMAIN_CF_APIKEY" \
       -H "X-Auth-Email: $DOMAIN_CF_EMAIL" | jq -r '.result[0].id'
}

enable_performance_plan() {
  local api_url="https://main.bigscoots.com/bscache-usage-log/api/"
  local content_type="Content-Type: application/json"
  local security_header="x-bigscoots-user: webmaster"
  local server_ip="$serverip"
  local hostname="$CFAPI_CANONICALDOMAIN"
  local server_hostname="$(hostname)"
  local data='{
    "action": "enable_plan",
    "hostname": "'"$hostname"'",
    "server_ip": "'"$server_ip"'",
    "server_hostname": "'"$server_hostname"'",
    "plan": "performance+"
  }'

  local response=$(curl -s --header "$content_type" --header "$security_header" --data "$data" "$api_url")

  if [[ $response == *"\"success\": false"* ]]
  then
    send_slack_alert "#wpo-alerts" ":warning:" "Function: \`enable_standard_plan\`" "$hostname" "$response"
  fi
}

update_master_db() {
  local api_url="https://main.bigscoots.com/cf-custom-hostnames/"
  local content_type="Content-Type: application/json"
  local security_header="x-bigscoots-user: webmaster"
  local hostname="$CFAPI_CANONICALDOMAIN"
  local step3_file_path="/root/cfplugin/${DOMAIN}.step3.api"
  local custom_host_name_id

  if [ ! -f "$step3_file_path" ]
  then
    send_slack_alert "#wpo-alerts" ":warning:" "Function: \`update_master_db\`" "$hostname" "File does not exist. \`\`\`file: $step3_file_path\`\`\`"
    return 1
  fi

  custom_host_name_id=$(cat "$step3_file_path" | jq -r ".result.id")

  if [ -z "$custom_host_name_id" ] || [ "$custom_host_name_id" == "null" ] 
  then
    send_slack_alert "#wpo-alerts" ":warning:" "Function: \`update_master_db\`" "$hostname" "Custom Hostname ID is empty. \`\`\`file: $step3_file_path\`\`\`"
    return 1
  fi

  local data='{
    "action": "add_record",
    "hostname": "'"$hostname"'",
    "hostname_id": "'"$custom_host_name_id"'"
  }'
  
  local response=$(curl -s --header "$content_type" --header "$security_header" -X POST --data "$data" "$api_url")

  if [[ $response == *"\"success\": false"* ]]
  then
    send_slack_alert "#wpo-alerts" ":warning:" "Function: \`update_master_db\`" "$hostname" "$response"
  fi
}

# If --run is provided, execute the main process
if [[ $RUN -eq 1 ]]; then
    main_process() {
        if [[ -z "$DOMAIN_CF_ZONEID" && -n "$DOMAIN_CF_EMAIL" && -n "$DOMAIN_CF_APIKEY" ]]
        then
            DOMAIN_CF_ZONEID=$(GET_ZONE_ID)
        fi
        HASH=$(get_wpo_api_hash)
        GEN_PKEY
        DEPLOY_PKEY
        FINALSTEPS
        GATHERCFAPI
        FIX_NONCANONICAL_DNS
        ADDDNSCFAPI
        ADDCHNAMECFAPI
        MDFYCHNAMECFAPI
        GETCHNAMEINFO
        VRFYCFAPI

        # Now changes to the free Cloudflare account
        UPDATE_DNS_RECORD
        GRAY_CLOUD_DOMAIN

        enable_performance_plan
        update_master_db
        
        CHK_CF_CUSTOM_HOSTNAME_STATUS
        UPDATE_DNS_CFENT_CNAME
    }
    # Run the main process directly
    main_process
    exit 0
fi

# If --run is not provided, start the process in a screen session
SCREEN_NAME="cf_deploy_${DOMAIN}"
echo '{"errors": [], "messages": ["Process started successfully"], "success": true, "result": {}}'
screen -dmS "$SCREEN_NAME" bash -c "$0 --domain \"$DOMAIN\" --ip \"$IP\" --email \"$DOMAIN_CF_EMAIL\" --apikey \"$DOMAIN_CF_APIKEY\" $ZONEID_ARG --run"