#!/usr/bin/env bash is_valid_email_address() { local value="${1}" case "${value}" in *@*.*) return 0 ;; *) return 1 ;; esac } is_valid_port_number() { local value="${1}" if ! [[ "${value}" =~ ^[0-9]+$ ]]; then return 1 fi if [ "${value}" -lt 1 ] || [ "${value}" -gt 65535 ]; then return 1 fi return 0 } EASY_DOCKER_LAST_INVALID_DOMAIN="" reset_domain_validation_feedback() { EASY_DOCKER_LAST_INVALID_DOMAIN="" } trim_domain_token() { local result_var="${1}" local value="${2}" while true; do case "${value}" in ' '*) value="${value# }" ;; *' ') value="${value% }" ;; $'\t'*) value="${value#$'\t'}" ;; *$'\t') value="${value%$'\t'}" ;; *) break ;; esac done printf -v "${result_var}" "%s" "${value}" return 0 } normalize_domain_token() { local result_var="${1}" local raw_token="${2}" local token="${raw_token}" trim_domain_token token "${token}" if [ -z "${token}" ]; then return 1 fi while true; do case "${token}" in \"*\") token="${token#\"}" token="${token%\"}" ;; \'*\') token="${token#\'}" token="${token%\'}" ;; \`*\`) token="${token#\`}" token="${token%\`}" ;; \[*\]) token="${token#\[}" token="${token%\]}" ;; \(*\)) token="${token#(}" token="${token%)}" ;; \"*) token="${token#\"}" ;; \'*) token="${token#\'}" ;; \`*) token="${token#\`}" ;; \[*) token="${token#\[}" ;; \(*) token="${token#(}" ;; *) break ;; esac done while true; do case "${token}" in *\") token="${token%\"}" ;; *\') token="${token%\'}" ;; *\`) token="${token%\`}" ;; *\]) token="${token%\]}" ;; *\)) token="${token%)}" ;; *) break ;; esac done trim_domain_token token "${token}" if [ -z "${token}" ]; then return 1 fi printf -v "${result_var}" "%s" "${token}" return 0 } is_valid_domain_name() { local domain="${1}" local normalized_domain="" local label="" local tld="" local last_index=0 local -a labels=() if ! normalize_domain_token normalized_domain "${domain}"; then return 1 fi case "${normalized_domain}" in *[[:space:],:/?#!@]* | *";"* | .* | *. | *..* | *\**) return 1 ;; esac if [ "${normalized_domain}" = "localhost" ]; then return 0 fi if [ "${#normalized_domain}" -lt 5 ] || [ "${#normalized_domain}" -gt 253 ]; then return 1 fi local IFS='.' read -r -a labels <<<"${normalized_domain}" if [ "${#labels[@]}" -lt 2 ]; then return 1 fi for label in "${labels[@]}"; do if [ -z "${label}" ]; then return 1 fi if [ "${#label}" -gt 63 ]; then return 1 fi case "${label}" in [A-Za-z0-9]*) ;; *) return 1 ;; esac case "${label}" in *[A-Za-z0-9]) ;; *) return 1 ;; esac case "${label}" in *[!A-Za-z0-9-]*) return 1 ;; esac done last_index=$((${#labels[@]} - 1)) tld="${labels[last_index]}" if [ "${tld}" = "localhost" ]; then return 0 fi if ! [[ "${tld}" =~ ^[A-Za-z]{2,63}$ ]]; then return 1 fi return 0 } parse_domains_input_to_lines() { local result_var="${1}" local raw_value="${2}" local sanitized_value="" local token="" local normalized_token="" local parsed_domain_lines="" local -a tokens=() local IFS=$' \t\n' reset_domain_validation_feedback sanitized_value="${raw_value//$'\r'/ }" sanitized_value="${sanitized_value//$'\n'/ }" sanitized_value="${sanitized_value//$'\t'/ }" sanitized_value="${sanitized_value//,/ }" sanitized_value="${sanitized_value//;/ }" read -r -a tokens <<<"${sanitized_value}" if [ "${#tokens[@]}" -eq 0 ]; then EASY_DOCKER_LAST_INVALID_DOMAIN="${raw_value}" return 1 fi for token in "${tokens[@]}"; do if ! normalize_domain_token normalized_token "${token}"; then EASY_DOCKER_LAST_INVALID_DOMAIN="${token}" return 1 fi if ! is_valid_domain_name "${normalized_token}"; then EASY_DOCKER_LAST_INVALID_DOMAIN="${normalized_token}" return 1 fi if [ -z "${parsed_domain_lines}" ]; then parsed_domain_lines="${normalized_token}" else parsed_domain_lines="${parsed_domain_lines}"$'\n'"${normalized_token}" fi done if [ -z "${parsed_domain_lines}" ]; then return 1 fi printf -v "${result_var}" "%s" "${parsed_domain_lines}" return 0 } domain_lines_to_csv() { local domain_lines="${1}" local domain="" local csv_value="" while IFS= read -r domain; do if [ -z "${domain}" ]; then continue fi if [ -z "${csv_value}" ]; then csv_value="${domain}" else csv_value="${csv_value},${domain}" fi done <