#!/bin/bash
# shellcheck disable=SC2034
dns_wix_info='WIX
Site: wix.com
Options:
WIX_API_TOKEN API Token
WIX_API_ID API ID
'
# DNS API DEV-Guide: https://github-wiki-see.page/m/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide
# WIX API DEV-Guide: https://dev.wix.com/docs/api-reference/account-level/domains/domain-dns/get-dns-zone
WIX_API="https://www.wixapis.com/domains/v1"
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_wix_add()
{
# Step 1: Get full domain and the txt record
FULLDOMAIN=$1
TXTVALUE=$2
# Step 2: The credentials such as username, password, api key or api token etc,
# must be saved so that acme.sh can renew the cert automatically in future.
# It will reuse the credentials automatically.
WIX_API_ID="${WIX_API_ID:-$(_readaccountconf_mutable WIX_API_ID)}"
WIX_API_TOKEN="${WIX_API_TOKEN:-$(_readaccountconf_mutable WIX_API_TOKEN)}"
if [ -z "${WIX_API_ID}" ] || [ -z "${WIX_API_TOKEN}" ]; then
WIX_API_ID=""
WIX_API_TOKEN=""
_err "You don't specify wix api key and email yet."
_err "Please create your key and try again."
return 1
fi
# save the credentials to the account conf file.
_saveaccountconf_mutable WIX_API_ID "${WIX_API_ID}"
_saveaccountconf_mutable WIX_API_TOKEN "${WIX_API_TOKEN}"
# Step 3: Detect which part is my root zone
_debug "dns_wix_add: First detect the root zone"
if ! _get_root "${FULLDOMAIN}"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "${_domain_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${_domain}"
_debug "Getting txt records"
_wix_rest GET "dns-zones/${_domain_id}"
if test "$?" != "0" -o -z "${RESPONSE}"; then
_err "Error"
return 1
fi
# Step 4: Call your dns api to add txt record
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
# we can not use updating anymore.
_info "Adding record"
if _wix_rest PATCH "dns-zones/${_domain_id}" "{\"domainName\": \"${_domain_id}\", \"additions\": [{\"type\":\"TXT\",\"hostName\":\"${FULLDOMAIN}\",\"values\":[\"${TXTVALUE}\"],\"ttl\":120}]}"; then
if _contains "${RESPONSE}" "${TXTVALUE}"; then
_info "Added, OK"
return 0
elif _contains "${RESPONSE}" "resource already exists"; then
_info "Already exists, OK"
return 0
elif _contains "${RESPONSE}" "domainName is not a valid hostname"; then
_err "invalid request, response \"${RESPONSE}\"."
return 1
else
_err "Add txt record error, response \"${RESPONSE}\"."
return 1
fi
fi
_err "Add txt record error, http request failed."
return 1
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
# fulldomain txtvalue
dns_wix_rm()
{
# Step 1: Get full domain and the txt record
FULLDOMAIN=$1
TXTVALUE=$2
# Step 2: The credentials such as username, password, api key or api token etc
WIX_API_ID="${WIX_API_ID:-$(_readaccountconf_mutable WIX_API_ID)}"
WIX_API_TOKEN="${WIX_API_TOKEN:-$(_readaccountconf_mutable WIX_API_TOKEN)}"
# Step 3: Detect which part is my root zone
_debug "dns_wix_rm: First detect the root zone"
if ! _get_root "${FULLDOMAIN}"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "${_domain_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${_domain}"
_debug "Getting txt records"
_wix_rest GET "dns-zones/${_domain}"
if test "$?" != "0" -o -z "${RESPONSE}"; then
_err "Error"
return 1
fi
_debug response "${RESPONSE}"
# Step 5: Call dns api to delete txt record
if _wix_rest PATCH "dns-zones/${_domain_id}" "{\"domainName\": \"${_domain_id}\", \"deletions\": [{\"type\":\"TXT\",\"hostName\":\"${FULLDOMAIN}\",\"values\":[\"${TXTVALUE}\"]}]}"; then
if _contains "${RESPONSE}" "domainName is not a valid hostname"; then
_err "domainName is not a valid hostname"
return 1
fi
_info "TXT record removed."
return 0
fi
_err "Delete txt record error, http request failed, response \"${RESPONSE}\"."
return 1
}
#################### Private functions below ##################################
# Detect which part is your root zone
# The full domain could be in either one of the following formats:
#
# _acme-challenge.www.example.com
# _acme-challenge.example.com
# _acme-challenge.example.co.uk
# _acme-challenge.www.example.co.uk
# _acme-challenge.sub1.sub2.www.example.co.uk
# sub1.sub2.example.co.uk
#
#_acme-challenge.www.domain.com
#returns
# _domain_id=domain.com from "id":"domain.com"
# _sub_domain=www.domain.com
# _domain=domain.com
#
_get_root()
{
DOMAIN=$1
i=1
p=1
_debug2 "wix: _get_root"
while true; do
HOST=$(printf "%s" "${DOMAIN}" | cut -d . -f "$i"-100)
_debug HOST "${HOST}"
if test -z "${HOST}"; then
# not valid
_err "_get_root: empty host not valid"
return 1
fi
if ! _wix_rest GET "dns-zones/${HOST}"; then
_err "_get_root: no response"
return 1
fi
_debug2 _get_root: response "${RESPONSE}"
if _contains "${RESPONSE}" "\"domainName\":\"${HOST}\""; then
_domain_id=$(echo "${RESPONSE}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
_sub_domain=$(printf "%s" "${HOST}" | cut -d . -f 1-"$p")
_domain=${HOST}
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_wix_rest()
{
METHOD=$1
ENDPOINT="$2"
DATA="$3"
_debug "${ENDPOINT}"
#export _H1="Content-Type: application/json"
export _H1="wix-account-id: ${WIX_API_ID}"
export _H2="Authorization: ${WIX_API_TOKEN}"
if test "${METHOD}" != "GET"; then
_debug data "${DATA}"
RESPONSE="$(_post "${DATA}" "${WIX_API}/${ENDPOINT}" "" "${METHOD}" application/json)"
else
RESPONSE="$(_get "${WIX_API}/${ENDPOINT}")"
fi
if test "$?" != "0"; then
_err "error ${ENDPOINT}"
return 1
fi
_debug2 response "${RESPONSE}"
return 0
}