diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index ea446d8462..435fd6b510 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -15,6 +15,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + DOCKER_IMAGE: neilpang/acme.sh jobs: CheckToken: @@ -44,6 +46,11 @@ jobs: uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5.5.1 + with: + images: ${DOCKER_IMAGE} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: login to docker hub @@ -51,8 +58,6 @@ jobs: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - name: build and push the image run: | - DOCKER_IMAGE=neilpang/acme.sh - if [[ $GITHUB_REF == refs/tags/* ]]; then DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/} fi @@ -66,8 +71,14 @@ jobs: fi fi + DOCKER_LABELS=() + while read -r label; do + DOCKER_LABELS+=(--label "${label}") + done <<<"${DOCKER_METADATA_OUTPUT_LABELS}" + docker buildx build \ --tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \ + "${DOCKER_LABELS[@]}" \ --output "type=image,push=true" \ --build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \ --platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x . diff --git a/acme.sh b/acme.sh index 4cf407f26c..e39a146be2 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=3.0.8 +VER=3.1.0 PROJECT_NAME="acme.sh" @@ -672,8 +672,10 @@ _hex_dump() { #0 1 2 3 4 5 6 7 8 9 - _ . ~ #30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e +#_url_encode [upper-hex] the encoded hex will be upper-case if the argument upper-hex is followed #stdin stdout _url_encode() { + _upper_hex=$1 _hex_str=$(_hex_dump) _debug3 "_url_encode" _debug3 "_hex_str" "$_hex_str" @@ -883,6 +885,9 @@ _url_encode() { ;; #other hex *) + if [ "$_upper_hex" = "upper-hex" ]; then + _hex_code=$(printf "%s" "$_hex_code" | _upper_case) + fi printf '%%%s' "$_hex_code" ;; esac @@ -2361,7 +2366,7 @@ _clear_conf() { _sdkey="$2" if [ "$_c_c_f" ]; then _conf_data="$(cat "$_c_c_f")" - echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" >"$_c_c_f" + echo "$_conf_data" | sed "/^$_sdkey *=.*$/d" >"$_c_c_f" else _err "Config file is empty, cannot clear" fi @@ -5111,6 +5116,19 @@ $_authorizations_map" _on_issue_err "$_post_hook" "$vlist" return 1 fi + _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r') + _sleep_overload_retry_sec=$_retryafter + if [ "$_sleep_overload_retry_sec" ]; then + if [ $_sleep_overload_retry_sec -le 600 ]; then + _sleep $_sleep_overload_retry_sec + else + _info "The retryafter=$_retryafter value is too large (> 600), will not retry anymore." + _clearupwebbroot "$_currentRoot" "$removelevel" "$token" + _clearup + _on_issue_err "$_post_hook" "$vlist" + return 1 + fi + fi done done diff --git a/deploy/ali_cdn.sh b/deploy/ali_cdn.sh index 6bbb3b4383..70a2e532b8 100644 --- a/deploy/ali_cdn.sh +++ b/deploy/ali_cdn.sh @@ -1,17 +1,23 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034,SC2154 # Script to create certificate to Alibaba Cloud CDN # +# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-cdn-or-dcdn-of-alibaba-cloud-aliyun +# # This deployment required following variables # export Ali_Key="ALIACCESSKEY" # export Ali_Secret="ALISECRETKEY" +# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi +# +# To specify the CDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates # export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com" -# If you have more than one domain, just +# If you have multiple CDN domains using the same certificate, just # export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com" # -# The credentials are shared with all domains, also shared with dns_ali api +# For DCDN, see ali_dcdn deploy hook -Ali_API="https://cdn.aliyuncs.com/" +Ali_CDN_API="https://cdn.aliyuncs.com/" ali_cdn_deploy() { _cdomain="$1" @@ -26,18 +32,16 @@ ali_cdn_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" - Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" - if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then - Ali_Key="" - Ali_Secret="" - _err "You don't specify aliyun api key and secret yet." + # Load dnsapi/dns_ali.sh to reduce the duplicated codes + # https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 + dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)" + # shellcheck source=/dev/null + if ! . "$dnsapi_ali"; then + _err "Error loading file $dnsapi_ali. Please check your API file and try again." return 1 fi - #save the api key and secret to the account conf file. - _saveaccountconf_mutable Ali_Key "$Ali_Key" - _saveaccountconf_mutable Ali_Secret "$Ali_Secret" + _prepare_ali_credentials || return 1 _getdeployconf DEPLOY_ALI_CDN_DOMAIN if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then @@ -47,8 +51,8 @@ ali_cdn_deploy() { fi # read cert and key files and urlencode both - _cert=$(_url_encode_upper <"$_cfullchain") - _key=$(_url_encode_upper <"$_ckey") + _cert=$(_url_encode upper-hex <"$_cfullchain") + _key=$(_url_encode upper-hex <"$_ckey") _debug2 _cert "$_cert" _debug2 _key "$_key" @@ -64,82 +68,9 @@ ali_cdn_deploy() { return 0 } -#################### Private functions below ################################## - -# act ign mtd -_ali_rest() { - act="$1" - ign="$2" - mtd="$3" - - signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) - signature=$(_ali_urlencode "$signature") - url="$Ali_API?$query&Signature=$signature" - - if [ "$mtd" = "GET" ]; then - response="$(_get "$url")" - else - # post payload is not supported yet because of signature - response="$(_post "" "$url")" - fi - - _ret="$?" - _debug2 response "$response" - if [ "$_ret" != "0" ]; then - _err "Error <$act>" - return 1 - fi - - if [ -z "$ign" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_ali_urlencode() { - _str="$1" - _str_len=${#_str} - _u_i=1 - while [ "$_u_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" - case $_str_c in [a-zA-Z0-9.~_-]) - printf "%s" "$_str_c" - ;; - *) - printf "%%%02X" "'$_str_c" - ;; - esac - _u_i="$(_math "$_u_i" + 1)" - done -} - -_ali_nonce() { - #_head_n 1 /dev/null 2>&1; then + cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original + _info "Updating system configuration for cipher compatibility." + _info "Saved original system config to /usr/lib/unifi/data/system.properties_original" + sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>/usr/lib/unifi/data/system.properties + sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>/usr/lib/unifi/data/system.properties + _info "System configuration updated." fi + rm "$_import_pkcs12" + + # Restarting unifi-core will bring up unifi, doing it out of order results in + # a certificate error, and breaks wifiman. + # Restart if we aren't doing unifi-core, otherwise stop for later restart. if systemctl -q is-active unifi; then - _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" + if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi" + else + _reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl stop unifi" + fi fi _services_updated="${_services_updated} unifi" _info "Install Unifi Controller certificate success!" @@ -165,6 +212,11 @@ unifi_deploy() { return 1 fi + # Save the existing certs in case something goes wrong. + cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt + cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key + _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key" diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 9bdfc20b65..0f1626f54f 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -9,25 +9,19 @@ Options: Ali_Secret API Secret ' -Ali_API="https://alidns.aliyuncs.com/" +# NOTICE: +# This file is referenced by Alibaba Cloud Services deploy hooks +# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276 +# Be careful when modifying this file, especially when making breaking changes for common functions + +Ali_DNS_API="https://alidns.aliyuncs.com/" #Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_ali_add() { fulldomain=$1 txtvalue=$2 - Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" - Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" - if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then - Ali_Key="" - Ali_Secret="" - _err "You don't specify aliyun api key and secret yet." - return 1 - fi - - #save the api key and secret to the account conf file. - _saveaccountconf_mutable Ali_Key "$Ali_Key" - _saveaccountconf_mutable Ali_Secret "$Ali_Secret" + _prepare_ali_credentials || return 1 _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -52,7 +46,67 @@ dns_ali_rm() { _clean } -#################### Private functions below ################################## +#################### Alibaba Cloud common functions below #################### + +_prepare_ali_credentials() { + Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" + Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" + if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then + Ali_Key="" + Ali_Secret="" + _err "You don't specify aliyun api key and secret yet." + return 1 + fi + + #save the api key and secret to the account conf file. + _saveaccountconf_mutable Ali_Key "$Ali_Key" + _saveaccountconf_mutable Ali_Secret "$Ali_Secret" +} + +# act ign mtd +_ali_rest() { + act="$1" + ign="$2" + mtd="${3:-GET}" + + signature=$(printf "%s" "$mtd&%2F&$(printf "%s" "$query" | _url_encode upper-hex)" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) + signature=$(printf "%s" "$signature" | _url_encode upper-hex) + url="$endpoint?Signature=$signature" + + if [ "$mtd" = "GET" ]; then + url="$url&$query" + response="$(_get "$url")" + else + response="$(_post "$query" "$url" "" "$mtd" "application/x-www-form-urlencoded")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" != "0" ]; then + _err "Error <$act>" + return 1 + fi + + if [ -z "$ign" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then + _err "$message" + return 1 + fi + fi +} + +_ali_nonce() { + #_head_n 1 " - return 1 - fi - - _debug2 response "$response" - if [ -z "$2" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_ali_urlencode() { - _str="$1" - _str_len=${#_str} - _u_i=1 - while [ "$_u_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" - case $_str_c in [a-zA-Z0-9.~_-]) - printf "%s" "$_str_c" - ;; - *) - printf "%%%02X" "'$_str_c" - ;; - esac - _u_i="$(_math "$_u_i" + 1)" - done -} - -_ali_nonce() { - #_head_n 1 /\>/g") + _s=$(echo "$_s" | sed 's/"/\"/g') + printf -- %s "$_s" +} + _inwx_login() { if _inwx_check_cookie; then @@ -170,6 +179,8 @@ _inwx_login() { return 0 fi + XML_PASS=$(_htmlEscape "$INWX_Password") + xml_content=$(printf ' account.login @@ -193,7 +204,7 @@ _inwx_login() { - ' "$INWX_User" "$INWX_Password") + ' "$INWX_User" "$XML_PASS") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 7fd0d99c65..edc789e105 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -14,6 +14,8 @@ Options: # User must provide login data and URL to the ISPConfig installation incl. port. # The remote user in ISPConfig must have access to: # - DNS txt Functions +# - DNS zone functions +# - Client functions ######## Public functions ##################### diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 2bc3d38204..d5dbbcbcbb 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -39,13 +39,15 @@ dns_nsupdate_add() { [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d" [ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D" if [ -z "${NSUPDATE_ZONE}" ]; then - nsupdate -k "${NSUPDATE_KEY}" $nsdebug "${NSUPDATE_OPT}" <.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi @@ -152,7 +152,7 @@ dns_openprovider_rm() { new_item="$(echo "$item" | sed -n 's/.*.*\(\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(.*<\/type>\).*\(.*<\/value>\).*\(.*<\/prio>\).*\(.*<\/ttl>\)\).*<\/item>.*/\2<\/name>\3\4\5\6<\/item>/p')" fi - if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA|NS)<\/type>.*")" ]; then + if [ -z "$(echo "$new_item" | _egrep_o ".*(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then _debug "not an allowed record type, skipping" "$new_item" continue fi diff --git a/dnsapi/dns_timeweb.sh b/dnsapi/dns_timeweb.sh index 2edca180a6..9860872c74 100644 --- a/dnsapi/dns_timeweb.sh +++ b/dnsapi/dns_timeweb.sh @@ -110,9 +110,9 @@ _timeweb_split_acme_fqdn() { TW_Page_Limit=100 TW_Page_Offset=0 + TW_Domains_Returned="" - while [ -z "$TW_Domains_Total" ] || - [ "$((TW_Domains_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do + while [ -z "$TW_Domains_Returned" ] || [ "$TW_Domains_Returned" -ge "$TW_Page_Limit" ]; do _timeweb_list_domains "$TW_Page_Limit" "$TW_Page_Offset" || return 1 @@ -160,9 +160,10 @@ _timeweb_get_dns_txt() { TW_Page_Limit=100 TW_Page_Offset=0 + TW_Dns_Records_Returned="" + + while [ -z "$TW_Dns_Records_Returned" ] || [ "$TW_Dns_Records_Returned" -ge "$TW_Page_Limit" ]; do - while [ -z "$TW_Dns_Records_Total" ] || - [ "$((TW_Dns_Records_Total + TW_Page_Limit))" -gt "$((TW_Page_Offset + TW_Page_Limit))" ]; do _timeweb_list_dns_records "$TW_Page_Limit" "$TW_Page_Offset" || return 1 while @@ -195,7 +196,7 @@ _timeweb_get_dns_txt() { # Param 2: Offset for domains list. # # Sets the "TW_Domains" variable. -# Sets the "TW_Domains_Total" variable. +# Sets the "TW_Domains_Returned" variable. _timeweb_list_domains() { _debug "Listing domains via Timeweb Cloud API. Limit: $1, offset: $2." @@ -211,22 +212,22 @@ _timeweb_list_domains() { return 1 } - TW_Domains_Total=$( + TW_Domains_Returned=$( echo "$TW_Domains" | sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' ) - [ -z "$TW_Domains_Total" ] && { + [ -z "$TW_Domains_Returned" ] && { _err "Failed to extract the total count of domains." return 1 } - [ "$TW_Domains_Total" -eq "0" ] && { + [ "$TW_Domains_Returned" -eq "0" ] && { _err "Domains are missing." return 1 } - _debug "Total count of domains in the Timeweb Cloud account: $TW_Domains_Total." + _debug "Domains returned by Timeweb Cloud API: $TW_Domains_Returned." } # Lists domain DNS records via the Timeweb Cloud API. @@ -235,7 +236,7 @@ _timeweb_list_domains() { # Param 2: Offset for DNS records list. # # Sets the "TW_Dns_Records" variable. -# Sets the "TW_Dns_Records_Total" variable. +# Sets the "TW_Dns_Records_Returned" variable. _timeweb_list_dns_records() { _debug "Listing domain DNS records via the Timeweb Cloud API. Limit: $1, offset: $2." @@ -251,22 +252,22 @@ _timeweb_list_dns_records() { return 1 } - TW_Dns_Records_Total=$( + TW_Dns_Records_Returned=$( echo "$TW_Dns_Records" | sed 's/.*"meta":{"total":\([0-9]*\)[^0-9].*/\1/' ) - [ -z "$TW_Dns_Records_Total" ] && { + [ -z "$TW_Dns_Records_Returned" ] && { _err "Failed to extract the total count of DNS records." return 1 } - [ "$TW_Dns_Records_Total" -eq "0" ] && { + [ "$TW_Dns_Records_Returned" -eq "0" ] && { _err "DNS records are missing." return 1 } - _debug "Total count of DNS records: $TW_Dns_Records_Total." + _debug "DNS records returned by Timeweb Cloud API: $TW_Dns_Records_Returned." } # Verifies whether the domain is the primary domain for the ACME DNS-01 challenge FQDN. diff --git a/notify/bark.sh b/notify/bark.sh index bbd5bf344f..fd9ebd7669 100644 --- a/notify/bark.sh +++ b/notify/bark.sh @@ -1,32 +1,40 @@ #!/usr/bin/env sh -#Support iOS Bark Notification +# Support iOS Bark Notification -#BARK_API_URL="https://api.day.app/xxxx" -#BARK_SOUND="yyyy" -#BARK_GROUP="zzzz" +# Every parameter explained: https://github.com/Finb/bark-server/blob/master/docs/API_V2.md#push -# subject content statusCode +# BARK_API_URL="https://api.day.app/xxxx" (required) +# BARK_GROUP="ACME" (optional) +# BARK_SOUND="alarm" (optional) +# BARK_LEVEL="active" (optional) +# BARK_BADGE=0 (optional) +# BARK_AUTOMATICALLYCOPY="1" (optional) +# BARK_COPY="My clipboard Content" (optional) +# BARK_ICON="https://example.com/icon.png" (optional) +# BARK_ISARCHIVE="1" (optional) +# BARK_URL="https://example.com" (optional) + +# subject content statusCode bark_send() { _subject="$1" _content="$2" - _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _statusCode="$3" # 0: success, 1: error, 2: skipped _debug "_subject" "$_subject" _debug "_content" "$_content" _debug "_statusCode" "$_statusCode" + _content=$(echo "$_content" | _url_encode) + _subject=$(echo "$_subject" | _url_encode) + BARK_API_URL="${BARK_API_URL:-$(_readaccountconf_mutable BARK_API_URL)}" if [ -z "$BARK_API_URL" ]; then - BARK_API_URL="" _err "You didn't specify a Bark API URL BARK_API_URL yet." _err "You can download Bark from App Store and get yours." return 1 fi _saveaccountconf_mutable BARK_API_URL "$BARK_API_URL" - BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}" - _saveaccountconf_mutable BARK_SOUND "$BARK_SOUND" - BARK_GROUP="${BARK_GROUP:-$(_readaccountconf_mutable BARK_GROUP)}" if [ -z "$BARK_GROUP" ]; then BARK_GROUP="ACME" @@ -35,10 +43,79 @@ bark_send() { _saveaccountconf_mutable BARK_GROUP "$BARK_GROUP" fi - _content=$(echo "$_content" | _url_encode) - _subject=$(echo "$_subject" | _url_encode) + BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}" + if [ -n "$BARK_SOUND" ]; then + _saveaccountconf_mutable BARK_SOUND "$BARK_SOUND" + fi + + BARK_LEVEL="${BARK_LEVEL:-$(_readaccountconf_mutable BARK_LEVEL)}" + if [ -n "$BARK_LEVEL" ]; then + _saveaccountconf_mutable BARK_LEVEL "$BARK_LEVEL" + fi + + BARK_BADGE="${BARK_BADGE:-$(_readaccountconf_mutable BARK_BADGE)}" + if [ -n "$BARK_BADGE" ]; then + _saveaccountconf_mutable BARK_BADGE "$BARK_BADGE" + fi + + BARK_AUTOMATICALLYCOPY="${BARK_AUTOMATICALLYCOPY:-$(_readaccountconf_mutable BARK_AUTOMATICALLYCOPY)}" + if [ -n "$BARK_AUTOMATICALLYCOPY" ]; then + _saveaccountconf_mutable BARK_AUTOMATICALLYCOPY "$BARK_AUTOMATICALLYCOPY" + fi + + BARK_COPY="${BARK_COPY:-$(_readaccountconf_mutable BARK_COPY)}" + if [ -n "$BARK_COPY" ]; then + _saveaccountconf_mutable BARK_COPY "$BARK_COPY" + fi + + BARK_ICON="${BARK_ICON:-$(_readaccountconf_mutable BARK_ICON)}" + if [ -n "$BARK_ICON" ]; then + _saveaccountconf_mutable BARK_ICON "$BARK_ICON" + fi + + BARK_ISARCHIVE="${BARK_ISARCHIVE:-$(_readaccountconf_mutable BARK_ISARCHIVE)}" + if [ -n "$BARK_ISARCHIVE" ]; then + _saveaccountconf_mutable BARK_ISARCHIVE "$BARK_ISARCHIVE" + fi + + BARK_URL="${BARK_URL:-$(_readaccountconf_mutable BARK_URL)}" + if [ -n "$BARK_URL" ]; then + _saveaccountconf_mutable BARK_URL "$BARK_URL" + fi + + _params="" + + if [ -n "$BARK_SOUND" ]; then + _params="$_params&sound=$BARK_SOUND" + fi + if [ -n "$BARK_GROUP" ]; then + _params="$_params&group=$BARK_GROUP" + fi + if [ -n "$BARK_LEVEL" ]; then + _params="$_params&level=$BARK_LEVEL" + fi + if [ -n "$BARK_BADGE" ]; then + _params="$_params&badge=$BARK_BADGE" + fi + if [ -n "$BARK_AUTOMATICALLYCOPY" ]; then + _params="$_params&automaticallyCopy=$BARK_AUTOMATICALLYCOPY" + fi + if [ -n "$BARK_COPY" ]; then + _params="$_params©=$BARK_COPY" + fi + if [ -n "$BARK_ICON" ]; then + _params="$_params&icon=$BARK_ICON" + fi + if [ -n "$BARK_ISARCHIVE" ]; then + _params="$_params&isArchive=$BARK_ISARCHIVE" + fi + if [ -n "$BARK_URL" ]; then + _params="$_params&url=$BARK_URL" + fi + + _params=$(echo "$_params" | sed 's/^&//') # remove leading '&' if exists - response="$(_get "$BARK_API_URL/$_subject/$_content?sound=$BARK_SOUND&group=$BARK_GROUP")" + response="$(_get "$BARK_API_URL/$_subject/$_content?$_params")" if [ "$?" = "0" ] && _contains "$response" "success"; then _info "Bark API fired success."