@@ -1340,7 +1340,7 @@ cert_show() {
13401340 if [ -z " $DOMAIN_CERTS " ]; then
13411341 echo -e " ℹ️ ${COLOR_YELLOW} No certificates found for domain: $search_term ${CoR} "
13421342 else
1343- echo " $DOMAIN_CERTS " | jq -r ' " 🔒 ID: \(.id)\n • Domain(s): \(.domain_names | join(", "))\n • Provider : \(.provider)\n • Created on: \(.created_on // "N/A")\n • Expires on: \(.expires_on // "N/A")\n • Status: \(if .expired then "❌ EXPIRED" else if .expires_on then "✅ VALID" else "⚠️ PENDING" end end)"' | while IFS= read -r line; do if [[ $line == * " ❌ EXPIRED" * ]]; then echo -e " ${line/ ❌ EXPIRED/ ${COLOR_RED} ❌ EXPIRED${CoR} } " ; elif [[ $line == * " ✅ VALID" * ]]; then echo -e " ${line/ ✅ VALID/ ${COLOR_GREEN} ✅ VALID${CoR} } " ; elif [[ $line == * " ⚠️ PENDING" * ]]; then echo -e " ${line/ ⚠️ PENDING/ ${COLOR_YELLOW} ⚠️ PENDING${CoR} } " ; else echo -e " $line " ; fi ; done
1343+ echo " $DOMAIN_CERTS " | jq -r ' " 🔒 ID: \(.id)\n • Domain(s): \(.domain_names | join(", "))\n • Provider: \(.provider)\n • Created on: \(.created_on // "N/A")\n • Expires on: \(.expires_on // "N/A")\n • Status: \(if .expired then "❌ EXPIRED" else if .expires_on then "✅ VALID" else "⚠️ PENDING" end end)"' | while IFS= read -r line; do if [[ $line == * " ❌ EXPIRED" * ]]; then echo -e " ${line/ ❌ EXPIRED/ ${COLOR_RED} ❌ EXPIRED${CoR} } " ; elif [[ $line == * " ✅ VALID" * ]]; then echo -e " ${line/ ✅ VALID/ ${COLOR_GREEN} ✅ VALID${CoR} } " ; elif [[ $line == * " ⚠️ PENDING" * ]]; then echo -e " ${line/ ⚠️ PENDING/ ${COLOR_YELLOW} ⚠️ PENDING${CoR} } " ; else echo -e " $line " ; fi ; done
13441344 echo " "
13451345 fi
13461346}
@@ -1934,6 +1934,21 @@ host_search() {
19341934}
19351935
19361936# ###############################
1937+ # ###############################
1938+ # Enable a proxy host by ID
1939+ #
1940+ # 💡 NPM-specific endpoint discovery (2025-05-30):
1941+ # ================================================
1942+ # Like host_disable(), this function uses NPM's dedicated endpoint:
1943+ #
1944+ # ✅ CORRECT approach:
1945+ # POST /api/nginx/proxy-hosts/{id}/enable with empty body
1946+ # → Actually enables the site and makes it accessible
1947+ #
1948+ # ❌ The generic PUT approach with JSON modification doesn't work reliably.
1949+ # Reference: Same discovery as host_disable() function above.
1950+ # ###############################
1951+
19371952# Enable a proxy host by ID
19381953host_enable () {
19391954 local host_id=" $1 "
@@ -1946,34 +1961,31 @@ host_enable() {
19461961 fi
19471962
19481963 check_token_notverbose
1949-
19501964
1951- # Check if the proxy host exists and get its current configuration
1965+ # Check if the proxy host exists first
19521966 CHECK_RESPONSE=$( curl -s -X GET " $BASE_URL /nginx/proxy-hosts/$host_id " \
19531967 -H " Authorization: Bearer $( cat " $TOKEN_FILE " ) " )
19541968
19551969 if [ $? -eq 0 ] && [ -n " $CHECK_RESPONSE " ]; then
1970+ # Check if the host was found (not a 404 error)
1971+ if echo " $CHECK_RESPONSE " | jq -e ' .error' > /dev/null 2>&1 ; then
1972+ echo -e " ⛔ ${COLOR_RED} Proxy host with ID $host_id does not exist${CoR} "
1973+ return 1
1974+ fi
1975+
19561976 # Get domain name for display
19571977 DOMAIN_NAME=$( echo " $CHECK_RESPONSE " | jq -r ' .domain_names[0]' )
19581978
1959- # Create minimal payload with only the enabled property
1960- PAYLOAD=' {"enabled":true}'
1979+ echo -e " \n ${COLOR_YELLOW} 🔄 Enabling proxy host ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
19611980
1962- # Send PUT request with minimal payload
1963- RESPONSE=$( curl -s -X PUT " $BASE_URL /nginx/proxy-hosts/$host_id " \
1981+ # Use the CORRECT NPM endpoint: POST to /enable (like the web interface does)
1982+ RESPONSE=$( curl -s -X POST " $BASE_URL /nginx/proxy-hosts/$host_id /enable " \
19641983 -H " Authorization: Bearer $( cat " $TOKEN_FILE " ) " \
1965- -H " Content-Type: application/json" \
1966- -d " $PAYLOAD " )
1984+ -H " Content-Type: application/json; charset=UTF-8" )
19671985
19681986 if [ $? -eq 0 ] && ! echo " $RESPONSE " | jq -e ' .error' > /dev/null 2>&1 ; then
1969- if [ " $DOMAIN_NAME " != " null" ] && [ -n " $DOMAIN_NAME " ]; then
1970-
1971- echo -e " \n ${COLOR_YELLOW} 🔄 Enabling proxy host ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
1972- echo -e " ✅ ${COLOR_GREEN} Successfully enabled ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} \n"
1973-
1974- else
1975- echo -e " ℹ️ ${COLOR_YELLOW} No domain name associated with this host${CoR} "
1976- fi
1987+ echo -e " ✅ ${COLOR_GREEN} Successfully enabled ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
1988+ # echo -e " 🎯 ${COLOR_GREEN}Using NPM's native enable endpoint${CoR}\n"
19771989 else
19781990 ERROR_MSG=$( echo " $RESPONSE " | jq -r ' .error.message // "Unknown error"' )
19791991 echo -e " ⛔ ${COLOR_RED} Failed to enable proxy host: $ERROR_MSG ${CoR} "
@@ -1985,49 +1997,65 @@ host_enable() {
19851997
19861998# ###############################
19871999# Disable a proxy host by ID
2000+ #
2001+ # 🐛 IMPORTANT BUG DISCOVERY (2025-05-30):
2002+ # ==========================================
2003+ # The NPM web interface uses a DIFFERENT endpoint than expected!
2004+ #
2005+ # ❌ WRONG approach (what we tried before):
2006+ # PUT /api/nginx/proxy-hosts/{id} with modified JSON (enabled: false)
2007+ # → Shows "disabled" in interface but site remains ACCESSIBLE!
2008+ #
2009+ # ✅ CORRECT approach (what NPM web interface actually uses):
2010+ # POST /api/nginx/proxy-hosts/{id}/disable with empty body
2011+ # → Actually disables the site and makes it INACCESSIBLE!
2012+ #
2013+ # This was discovered by inspecting NPM web interface network traffic.
2014+ # NPM has dedicated /enable and /disable endpoints that work properly.
2015+ # Reference: GitHub issue #3 (nginx-proxy-manager-Bash-API)
2016+ # ###############################
19882017host_disable () {
19892018 local host_id=" $1 "
19902019
19912020 if [ -z " $host_id " ]; then
19922021 echo -e " \n ⛔ ${COLOR_RED} ERROR: The --host-disable option requires a host 🆔.${CoR} "
1993- echo -e " Usage : ${COLOR_ORANGE} $0 --host-disable <host_id>${CoR} "
1994- echo -e " Example: ${COLOR_GREEN} $0 --host-disable 42${CoR} "
2022+ echo -e " Usage : ${COLOR_ORANGE} $0 --host-disable <host_id>${CoR} "
2023+ echo -e " Example: ${COLOR_GREEN} $0 --host-disable 42${CoR} "
19952024 return 1
19962025 fi
19972026
19982027 check_token_notverbose
19992028
2000- # Check if the proxy host exists and get its current configuration
2029+ # Check if the proxy host exists first
20012030 CHECK_RESPONSE=$( curl -s -X GET " $BASE_URL /nginx/proxy-hosts/$host_id " \
20022031 -H " Authorization: Bearer $( cat " $TOKEN_FILE " ) " )
20032032
20042033 if [ $? -eq 0 ] && [ -n " $CHECK_RESPONSE " ]; then
2034+ # Check if the host was found (not a 404 error)
2035+ if echo " $CHECK_RESPONSE " | jq -e ' .error' > /dev/null 2>&1 ; then
2036+ echo -e " ⛔ ${COLOR_RED} Proxy host with ID $host_id does not exist${CoR} "
2037+ return 1
2038+ fi
2039+
20052040 # Get domain name for display
20062041 DOMAIN_NAME=$( echo " $CHECK_RESPONSE " | jq -r ' .domain_names[0]' )
20072042
2008- # Create minimal payload with only the enabled property
2009- PAYLOAD=' {"enabled":false}'
2043+ echo -e " \n ${COLOR_YELLOW} 🔄 Disabling proxy host ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
20102044
2011- # Send PUT request with minimal payload
2012- RESPONSE=$( curl -s -X PUT " $BASE_URL /nginx/proxy-hosts/$host_id " \
2045+ # Use the CORRECT NPM endpoint: POST to /disable (like the web interface does)
2046+ RESPONSE=$( curl -s -X POST " $BASE_URL /nginx/proxy-hosts/$host_id /disable " \
20132047 -H " Authorization: Bearer $( cat " $TOKEN_FILE " ) " \
2014- -H " Content-Type: application/json" \
2015- -d " $PAYLOAD " )
2048+ -H " Content-Type: application/json; charset=UTF-8" )
20162049
20172050 if [ $? -eq 0 ] && ! echo " $RESPONSE " | jq -e ' .error' > /dev/null 2>&1 ; then
2018-
2019- if [ " $DOMAIN_NAME " != " null" ] && [ -n " $DOMAIN_NAME " ]; then
2020- echo -e " \n ${COLOR_YELLOW} 🔄 Disabling proxy host ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
2021- echo -e " ✅ ${COLOR_GREEN} Successfully disabled ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} \n"
2022- else
2023- echo -e " ℹ️ ${COLOR_YELLOW} No domain name associated with this host${CoR} \n"
2024- fi
2051+ echo -e " ✅ ${COLOR_GREEN} Successfully disabled ${CoR} 🆔${COLOR_CYAN} $host_id ${CoR} 🌐Domain: ${COLOR_CYAN} $DOMAIN_NAME ${CoR} "
2052+ # echo -e " 🎯 ${COLOR_GREEN}Using NPM's native disable endpoint${CoR}\n"
20252053 else
20262054 ERROR_MSG=$( echo " $RESPONSE " | jq -r ' .error.message // "Unknown error"' )
2027- echo -e " ⛔ ${COLOR_RED} Failed to disable proxy host: $ERROR_MSG ${CoR} \n "
2055+ echo -e " ⛔ ${COLOR_RED} Failed to disable proxy host: $ERROR_MSG ${CoR} "
20282056 fi
20292057 else
2030- echo -e " ⛔ ${COLOR_RED} Proxy host with ID $host_id does not exist${CoR} \n "
2058+ echo -e " ⛔ ${COLOR_RED} Proxy host with ID $host_id does not exist${CoR} "
20312059 fi
20322060}
20332061
@@ -2150,7 +2178,7 @@ host_acl_enable() {
21502178host_acl_disable () {
21512179 if [ -z " $HOST_ID " ]; then
21522180 echo -e " \n ⛔ ${COLOR_RED} Error: HOST_ID is required to disable the ACL.${CoR} "
2153- echo -e " Usage: $0 --host-acl-disable <host_id>"
2181+ echo -e " Usage: $0 --host-acl-disable <host_id>\n "
21542182 exit 1
21552183 fi
21562184 check_token_notverbose
0 commit comments