From 37853b91dc54d0f6db830743e88b44a5209161eb Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:30:36 +0330 Subject: [PATCH] Fix Edit user --- core/scripts/hysteria2/edit_user.sh | 276 ++++++++++++++++------------ 1 file changed, 156 insertions(+), 120 deletions(-) diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh index e3f6931..f27d63c 100644 --- a/core/scripts/hysteria2/edit_user.sh +++ b/core/scripts/hysteria2/edit_user.sh @@ -3,77 +3,88 @@ source /etc/hysteria/core/scripts/utils.sh source /etc/hysteria/core/scripts/path.sh -# Function to validate all user input fields -validate_inputs() { - local new_username=$1 - local new_password=$2 - local new_traffic_limit=$3 - local new_expiration_days=$4 - local new_creation_date=$5 - local new_blocked=$6 +readonly GB_TO_BYTES=$((1024 * 1024 * 1024)) - # Validate username - if [ -n "$new_username" ]; then - if ! [[ "$new_username" =~ ^[a-zA-Z0-9]+$ ]]; then - echo -e "${red}Error:${NC} Username can only contain letters and numbers." - exit 1 - fi +validate_username() { + local username=$1 + if [ -z "$username" ]; then + return 0 # Optional value is valid fi - - # Validate traffic limit - if [ -n "$new_traffic_limit" ]; then - if ! [[ "$new_traffic_limit" =~ ^[0-9]+$ ]]; then - echo -e "${red}Error:${NC} Traffic limit must be a valid integer." - exit 1 - fi - fi - - # Validate expiration days - if [ -n "$new_expiration_days" ]; then - if ! [[ "$new_expiration_days" =~ ^[0-9]+$ ]]; then - echo -e "${red}Error:${NC} Expiration days must be a valid integer." - exit 1 - fi - fi - - # Validate date format - if [ -n "$new_creation_date" ]; then - if ! [[ "$new_creation_date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then - echo "Invalid date format. Expected YYYY-MM-DD." - exit 1 - elif ! date -d "$new_creation_date" >/dev/null 2>&1; then - echo "Invalid date. Please provide a valid date in YYYY-MM-DD format." - exit 1 - fi - fi - - # Validate blocked status - if [ -n "$new_blocked" ]; then - if [ "$new_blocked" != "true" ] && [ "$new_blocked" != "false" ] && [ "$new_blocked" != "y" ] && [ "$new_blocked" != "n" ]; then - echo -e "${red}Error:${NC} Blocked status must be 'true', 'false', 'y', or 'n'." - exit 1 - fi + if ! [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then + echo "Username can only contain letters and numbers." + return 1 fi + return 0 } -# Convert 'y'/'n' to 'true'/'false' + +validate_traffic_limit() { + local traffic_limit=$1 + if [ -z "$traffic_limit" ]; then + return 0 # Optional value is valid + fi + if ! [[ "$traffic_limit" =~ ^[0-9]+$ ]]; then + echo "Traffic limit must be a valid integer." + return 1 + fi + return 0 +} + +validate_expiration_days() { + local expiration_days=$1 + if [ -z "$expiration_days" ]; then + return 0 # Optional value is valid + fi + if ! [[ "$expiration_days" =~ ^[0-9]+$ ]]; then + echo "Expiration days must be a valid integer." + return 1 + fi + return 0 +} + +validate_date() { + local date_str=$1 + if [ -z "$date_str" ]; then + return 0 # Optional value is valid + fi + if ! [[ "$date_str" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then + echo "Invalid date format. Expected YYYY-MM-DD." + return 1 + elif ! date -d "$date_str" >/dev/null 2>&1; then + echo "Invalid date. Please provide a valid date in YYYY-MM-DD format." + return 1 + fi + return 0 +} + +validate_blocked_status() { + local status=$1 + if [ -z "$status" ]; then + return 0 # Optional value is valid + fi + if [ "$status" != "true" ] && [ "$status" != "false" ]; then + echo "Blocked status must be 'true' or 'false'." + return 1 + fi + return 0 +} + + convert_blocked_status() { local status=$1 case "$status" in y|Y) echo "true" ;; n|N) echo "false" ;; true|false) echo "$status" ;; - *) echo "false" ;; # Default to false if something unexpected + *) echo "false" ;; # Default to false for safety esac } -# Function to get user info from users.json get_user_info() { local username=$1 python3 $CLI_PATH get-user -u "$username" } -# Function to update user info in users.json update_user_info() { local old_username=$1 local new_username=$2 @@ -84,72 +95,69 @@ update_user_info() { local new_blocked=$7 if [ ! -f "$USERS_FILE" ]; then - echo "Error: File '$USERS_FILE' not found." + echo -e "${red}Error:${NC} File '$USERS_FILE' not found." return 1 fi - echo "Checking if user exists" - user_exists=$(jq -e --arg username "$old_username" '.[$username]' "$USERS_FILE") - if [ $? -ne 0 ]; then - echo "Error: User '$old_username' not found." + + user_exists=$(jq -e --arg username "$old_username" '.[$username]' "$USERS_FILE" >/dev/null 2>&1 ) + + if [ $? -ne 0 ]; then + echo -e "${red}Error:${NC} User '$old_username' not found." return 1 fi - echo "User exists." - # Get existing user data existing_user_data=$(jq --arg username "$old_username" '.[$username]' "$USERS_FILE") upload_bytes=$(echo "$existing_user_data" | jq -r '.upload_bytes // 0') download_bytes=$(echo "$existing_user_data" | jq -r '.download_bytes // 0') status=$(echo "$existing_user_data" | jq -r '.status // "Offline"') - # Debugging output - echo "Updating user:" - echo "Username: $new_username" - echo "Password: $new_password" - echo "Max Download Bytes: $new_max_download_bytes" - echo "Expiration Days: $new_expiration_days" - echo "Creation Date: $new_account_creation_date" - echo "Blocked: $new_blocked" + + echo "Updating user:" + echo "Username: $new_username" + echo "Password: ${new_password:-(not changed)}" + echo "Max Download Bytes: ${new_max_download_bytes:-(not changed)}" + echo "Expiration Days: ${new_expiration_days:-(not changed)}" + echo "Creation Date: ${new_account_creation_date:-(not changed)}" + echo "Blocked: $new_blocked" + # Update user fields, only if new values are provided - jq --arg old_username "$old_username" \ - --arg new_username "$new_username" \ - --arg password "${new_password:-null}" \ - --argjson max_download_bytes "${new_max_download_bytes:-null}" \ - --argjson expiration_days "${new_expiration_days:-null}" \ - --arg account_creation_date "${new_creation_date:-null}" \ - --argjson blocked "$(convert_blocked_status "${new_blocked:-false}")" \ - --argjson upload_bytes "$upload_bytes" \ - --argjson download_bytes "$download_bytes" \ - --arg status "$status" \ - ' - .[$new_username] = .[$old_username] | - del(.[$old_username]) | - .[$new_username] |= ( + jq \ + --arg old_username "$old_username" \ + --arg new_username "$new_username" \ + --arg password "${new_password:-null}" \ + --argjson max_download_bytes "${new_max_download_bytes:-null}" \ + --argjson expiration_days "${new_expiration_days:-null}" \ + --arg account_creation_date "${new_account_creation_date:-null}" \ + --argjson blocked "$(convert_blocked_status "${new_blocked:-false}")" \ + --argjson upload_bytes "$upload_bytes" \ + --argjson download_bytes "$download_bytes" \ + --arg status "$status" \ + ' + .[$new_username] = .[$old_username] | + del(.[$old_username]) | + .[$new_username] |= ( .password = ($password // .password) | .max_download_bytes = ($max_download_bytes // .max_download_bytes) | .expiration_days = ($expiration_days // .expiration_days) | .account_creation_date = ($account_creation_date // .account_creation_date) | - .blocked = $blocked | - .upload_bytes = $upload_bytes | + .blocked = $blocked | + .upload_bytes = $upload_bytes | .download_bytes = $download_bytes | .status = $status - )' "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" + ) + ' "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" - if [ $? -ne 0 ]; then - echo "Error: Failed to update user '$old_username' in '$USERS_FILE'." - return 1 - fi + if [ $? -ne 0 ]; then + echo "Failed to update user '$old_username' in '$USERS_FILE'." + return 1 + fi - python3 $CLI_PATH restart-hysteria2 - - if [ $? -ne 0 ]; then - echo "Error: Failed to restart Hysteria service." - exit 1 - fi + return 0 } -# Main function to edit user + edit_user() { local username=$1 local new_username=$2 @@ -159,50 +167,78 @@ edit_user() { local new_creation_date=$6 local new_blocked=$7 - # Get user info - user_info=$(get_user_info "$username") + + local user_info=$(get_user_info "$username") + if [ $? -ne 0 ] || [ -z "$user_info" ]; then - echo -e "${red}Error:${NC} User '$username' not found." - exit 1 + echo "User '$username' not found." + return 1 fi - # Extract user info local password=$(echo "$user_info" | jq -r '.password') local traffic_limit=$(echo "$user_info" | jq -r '.max_download_bytes') local expiration_days=$(echo "$user_info" | jq -r '.expiration_days') local creation_date=$(echo "$user_info" | jq -r '.account_creation_date') local blocked=$(echo "$user_info" | jq -r '.blocked') - # Validate all inputs - validate_inputs "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" + if ! validate_username "$new_username"; then + echo "Invalid username: $new_username" + return 1 + fi - # Set new values with validation - new_username=${new_username:-$username} - new_password=${new_password:-$password} - - # Convert traffic limit to bytes if provided, otherwise keep existing - if [ -n "$new_traffic_limit" ]; then - new_traffic_limit=$(echo "$new_traffic_limit * 1073741824" | bc) - else - new_traffic_limit=$traffic_limit + if ! validate_traffic_limit "$new_traffic_limit"; then + echo "Invalid traffic limit: $new_traffic_limit" + return 1 fi - new_expiration_days=${new_expiration_days:-$expiration_days} + + if ! validate_expiration_days "$new_expiration_days"; then + echo "Invalid expiration days: $new_expiration_days" + return 1 + fi + + + if ! validate_date "$new_creation_date"; then + echo "Invalid creation date: $new_creation_date" + return 1 + fi + + if ! validate_blocked_status "$new_blocked"; then + echo "Invalid blocked status: $new_blocked" + return 1 + fi + + + + new_username=${new_username:-$username} + new_password=${new_password:-$password} + + + if [ -n "$new_traffic_limit" ]; then + new_traffic_limit=$((new_traffic_limit * GB_TO_BYTES)) + else + new_traffic_limit=$traffic_limit + fi + + new_expiration_days=${new_expiration_days:-$expiration_days} new_creation_date=${new_creation_date:-$creation_date} new_blocked=$(convert_blocked_status "${new_blocked:-$blocked}") - # Update user info in JSON file - update_user_info "$username" "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" - python3 $CLI_PATH restart-hysteria2 + if ! update_user_info "$username" "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked"; then + return 1 # Update user failed + fi - if [ $? -ne 0 ]; then - echo "Error: Failed to restart Hysteria service." - exit 1 - fi + if [ $? -ne 0 ]; then + echo "Failed to restart Hysteria service." + return 1 + fi + + echo "User updated successfully." + return 0 # Operation complete without error. - echo "Hysteria service restarted successfully." } + # Run the script edit_user "$1" "$2" "$3" "$4" "$5" "$6" "$7"