Browse Source

Merge branch '1.9.4-beta' into release

Jaap Marcus 8 months ago
parent
commit
aae8b2b40b
76 changed files with 317 additions and 251 deletions
  1. 13 99
      .drone.yml
  2. 25 0
      CHANGELOG.md
  3. 1 1
      README.md
  4. 11 8
      bin/v-change-sys-service-config
  5. 2 1
      bin/v-change-web-domain-name
  6. 5 5
      bin/v-list-access-keys
  7. 5 5
      bin/v-update-user-counters
  8. 5 5
      bin/v-update-user-stats
  9. 4 8
      docs/_data/team.js
  10. 2 2
      docs/docs/community/hestia-nginx-cache.md
  11. 1 1
      docs/docs/server-administration/email.md
  12. 7 7
      func/backup.sh
  13. 18 7
      func/domain.sh
  14. 5 4
      func/main.sh
  15. 28 29
      install/deb/filemanager/filegator/dist/css/hst-custom.css
  16. 4 0
      install/deb/templates/mail/nginx/default.stpl
  17. 2 0
      install/deb/templates/mail/nginx/default_disabled.stpl
  18. 4 0
      install/deb/templates/mail/nginx/default_snappymail.stpl
  19. 4 0
      install/deb/templates/web/nginx/caching.stpl
  20. 4 0
      install/deb/templates/web/nginx/default.stpl
  21. 4 0
      install/deb/templates/web/nginx/hosting.stpl
  22. 1 1
      install/deb/templates/web/nginx/php-fpm/magento.stpl
  23. 1 1
      install/deb/templates/web/nginx/php-fpm/magento.tpl
  24. 1 1
      install/deb/templates/web/nginx/suspended.stpl
  25. 2 1
      install/deb/templates/web/nginx/suspended.tpl
  26. 2 2
      install/hst-install-debian.sh
  27. 4 3
      install/hst-install-ubuntu.sh
  28. 2 4
      install/hst-install.sh
  29. 1 1
      install/upgrade/upgrade.conf
  30. 32 0
      install/upgrade/versions/1.9.4.sh
  31. 2 2
      package-lock.json
  32. 1 1
      src/deb/hestia/control
  33. 1 1
      src/deb/nginx/control
  34. 1 1
      src/deb/php/control
  35. 6 2
      web/edit/server/hestiaweb/index.php
  36. BIN
      web/locale/ar/LC_MESSAGES/hestiacp.mo
  37. BIN
      web/locale/az/LC_MESSAGES/hestiacp.mo
  38. BIN
      web/locale/bg/LC_MESSAGES/hestiacp.mo
  39. BIN
      web/locale/bn/LC_MESSAGES/hestiacp.mo
  40. BIN
      web/locale/bs/LC_MESSAGES/hestiacp.mo
  41. BIN
      web/locale/ca/LC_MESSAGES/hestiacp.mo
  42. BIN
      web/locale/cs/LC_MESSAGES/hestiacp.mo
  43. BIN
      web/locale/da/LC_MESSAGES/hestiacp.mo
  44. BIN
      web/locale/de/LC_MESSAGES/hestiacp.mo
  45. BIN
      web/locale/el/LC_MESSAGES/hestiacp.mo
  46. BIN
      web/locale/es/LC_MESSAGES/hestiacp.mo
  47. BIN
      web/locale/fa/LC_MESSAGES/hestiacp.mo
  48. BIN
      web/locale/fi/LC_MESSAGES/hestiacp.mo
  49. BIN
      web/locale/fr/LC_MESSAGES/hestiacp.mo
  50. BIN
      web/locale/hr/LC_MESSAGES/hestiacp.mo
  51. BIN
      web/locale/hu/LC_MESSAGES/hestiacp.mo
  52. BIN
      web/locale/id/LC_MESSAGES/hestiacp.mo
  53. BIN
      web/locale/it/LC_MESSAGES/hestiacp.mo
  54. BIN
      web/locale/ja/LC_MESSAGES/hestiacp.mo
  55. BIN
      web/locale/ka/LC_MESSAGES/hestiacp.mo
  56. BIN
      web/locale/ko/LC_MESSAGES/hestiacp.mo
  57. BIN
      web/locale/ku/LC_MESSAGES/hestiacp.mo
  58. BIN
      web/locale/nl/LC_MESSAGES/hestiacp.mo
  59. BIN
      web/locale/no/LC_MESSAGES/hestiacp.mo
  60. BIN
      web/locale/pl/LC_MESSAGES/hestiacp.mo
  61. BIN
      web/locale/pt-br/LC_MESSAGES/hestiacp.mo
  62. BIN
      web/locale/pt/LC_MESSAGES/hestiacp.mo
  63. BIN
      web/locale/ro/LC_MESSAGES/hestiacp.mo
  64. BIN
      web/locale/ru/LC_MESSAGES/hestiacp.mo
  65. BIN
      web/locale/sk/LC_MESSAGES/hestiacp.mo
  66. BIN
      web/locale/sq/LC_MESSAGES/hestiacp.mo
  67. BIN
      web/locale/sr/LC_MESSAGES/hestiacp.mo
  68. BIN
      web/locale/sv/LC_MESSAGES/hestiacp.mo
  69. BIN
      web/locale/th/LC_MESSAGES/hestiacp.mo
  70. BIN
      web/locale/tr/LC_MESSAGES/hestiacp.mo
  71. BIN
      web/locale/uk/LC_MESSAGES/hestiacp.mo
  72. BIN
      web/locale/ur/LC_MESSAGES/hestiacp.mo
  73. BIN
      web/locale/vi/LC_MESSAGES/hestiacp.mo
  74. BIN
      web/locale/zh-cn/LC_MESSAGES/hestiacp.mo
  75. BIN
      web/locale/zh-tw/LC_MESSAGES/hestiacp.mo
  76. 106 48
      web/templates/includes/panel.php

+ 13 - 99
.drone.yml

@@ -1,114 +1,28 @@
 ---
 kind: pipeline
-type: ssh
-name: Ubuntu | Nginx + Apache2
-
-concurrency:
-  limit: 1
-
-server:
-  host:
-    from_secret: server_address
-  user:
-    from_secret: username
-  ssh_key:
-    from_secret: ssh_key
-
-platform:
-  os: linux
-  arch: amd64
-
-steps:
-  - name: Download submodules
-    image: alpine/git
-    commands:
-      - git submodule update --init --recursive
-  - name: Build Hestia package and install
-    commands:
-      - ./src/hst_autocompile.sh --hestia --install '~localsrc'
-  - name: Reset Web templates
-    commands:
-      - rm /usr/local/hestia/data/templates/web/nginx/php-fpm/*.*
-      - rm /usr/local/hestia/data/templates/web/nginx/*.*
-      - rm /usr/local/hestia/data/templates/web/apache2/php-fpm/*.*
-      - rm /usr/local/hestia/data/templates/web/apache2/*.*
-      - rm /usr/local/hestia/data/templates/web/php-fpm/*.*
-      - /usr/local/hestia/bin/v-update-web-templates
-  - name: Run system / user tests
-    commands:
-      - bats ./test/test.bats
-  - name: Run restore tests
-    commands:
-      - bats ./test/restore.bats
-  - name: Run config tests
-    commands:
-      - bats ./test/config-tests.bats
-
-trigger:
-  event: [pull_request, push]
-  ref:
-    - refs/heads/release
-    - refs/heads/prerelease
-    - refs/heads/servicing
-    - refs/heads/tests/*
-    - refs/heads/main
-    - refs/pull/*/head
-
----
-kind: pipeline
-type: ssh
-name: Debian | Nginx
-
-concurrency:
-  limit: 1
-
-server:
-  host:
-    from_secret: server_address2
-  user:
-    from_secret: username
-  ssh_key:
-    from_secret: ssh_key
+type: docker
+name: Run test build
 
 platform:
   os: linux
   arch: amd64
 
 steps:
-  - name: Download submodules
-    image: alpine/git
-    commands:
-      - git submodule update --init --recursive
-  - name: Build Hestia package install
-    commands:
-      - ./src/hst_autocompile.sh --hestia --install '~localsrc'
-  - name: Reset Web templates
-    commands:
-      - rm /usr/local/hestia/data/templates/web/nginx/php-fpm/*.*
-      - rm /usr/local/hestia/data/templates/web/nginx/*.*
-      - rm /usr/local/hestia/data/templates/web/apache2/php-fpm/*.*
-      - rm /usr/local/hestia/data/templates/web/apache2/*.*
-      - rm /usr/local/hestia/data/templates/web/php-fpm/*.*
-      - /usr/local/hestia/bin/v-update-web-templates
-  - name: Run system / user tests
-    commands:
-      - bats ./test/test.bats
-  - name: Run restore tests
+  - name: Build JS/CSS
+    image: node:current-slim
     commands:
-      - bats ./test/restore.bats
-  - name: Run config tests
+      - npm ci --ignore-scripts
+      - npm run build
+  - name: Build
+    image: debian:bookworm
     commands:
-      - bats ./test/config-tests.bats
+      - ln -snf /etc/localtime && echo CET > /etc/timezone
+      - ./src/hst_autocompile.sh --dontinstalldeps --hestia --debug --cross --noinstall --keepbuild '~localsrc'
+      - mkdir -p ./hestia/
+      - mv /tmp/hestiacp-src/deb/*.deb ./hestia/
 
 trigger:
-  event: [pull_request, push]
-  ref:
-    - refs/heads/release
-    - refs/heads/prerelease
-    - refs/heads/servicing
-    - refs/heads/tests/*
-    - refs/heads/main
-    - refs/pull/*/head
+  event: [push]
 
 ---
 kind: pipeline

+ 25 - 0
CHANGELOG.md

@@ -2,6 +2,31 @@
 
 All notable changes to this project will be documented in this file.
 
+## [1.9.4] - Service release
+
+- Dropping support for Ubuntu 20.04 for new installs
+
+### Bug fixes
+
+- Fix: 421 error on all web and mail domains after Apache 2.4.64 update (#5058)
+- Fix: Set default SOA retry value to 1800 for DENIC compliance (#5030)
+- Fix domain alias replacement logic when changing web domain (Fixes #5015) (#5041)
+- Fix ipv4_cidr validation (#5044)
+- Update magento.tpl / magento.stpl for healthcheck support (#5036)
+- Add: Show user and bandwidth quota in the dashboard
+- Sort backup file list before retention check (Fixes #5017) (#5018)
+- Improve logging of Spamhaus DQS lookups without exposing query key (#5011)
+- Bump Roundcube to version 1.6.11
+- Remove the apache2-suexec-pristine package from the Debian installer
+- Fix(#4979): Fixes domain redirects not being suspended (#4991)
+- Ensure newline at end of hestiaweb user crontab (#4992)
+- Allow slash when adding username to smtp relay (Fixes #4973) (#4974)
+- fix: prevent empty user variable from affecting multiple scripts (Fixes #4926) (#4928)
+- Fix editing Panel Cronjobs for hestiaweb (#4891)
+- Fix missing dependency proftpd-mod-crypto on Ubuntu (#4895)
+- Fix the way Hestia validates chain certificate (#4887)
+- Class change for latest version of file manager. (#4871)
+
 ## [1.9.3] - Service release
 
 ### Bug fixes

+ 1 - 1
README.md

@@ -4,7 +4,7 @@
 
 <h2 align="center">Lightweight and powerful control panel for the modern web</h2>
 
-<p align="center"><strong>Latest stable release:</strong> Version 1.9.2 | <a href="https://github.com/hestiacp/hestiacp/blob/release/CHANGELOG.md">View Changelog</a></p>
+<p align="center"><strong>Latest stable release:</strong> Version 1.9.4 | <a href="https://github.com/hestiacp/hestiacp/blob/release/CHANGELOG.md">View Changelog</a></p>
 
 <p align="center">
 	<a href="https://www.hestiacp.com/">HestiaCP.com</a> |

+ 11 - 8
bin/v-change-sys-service-config

@@ -109,14 +109,17 @@ if [ "$update" = 'yes' ] && [ "$restart" != 'no' ]; then
 		fi
 	fi
 
-	$BIN/v-restart-service "$service" > /dev/null 2>&1
-
-	if [ $? -ne 0 ]; then
-		for config in $dst; do
-			cat "$config.vst.back" > "$config"
-			rm -f "$config.vst.back"
-		done
-		check_result "$E_RESTART" "ERROR: $service failed to start with new configuration."
+	if [[ "$service" != "hestiaweb" ]]; then
+		$BIN/v-restart-service "$service" > /dev/null 2>&1
+		if [ $? -ne 0 ]; then
+			for config in $dst; do
+				cat "$config.vst.back" > "$config"
+				rm -f "$config.vst.back"
+			done
+			check_result "$E_RESTART" "ERROR: $service failed to start with new configuration."
+		fi
+	else
+		rm -f "$config.vst.back"
 	fi
 fi
 

+ 2 - 1
bin/v-change-web-domain-name

@@ -65,12 +65,13 @@ get_domain_values 'web'
 sed -i "s/DOMAIN='$domain'/DOMAIN='$new_domain'/" $USER_DATA/web.conf
 new_alias=$(echo "$ALIAS,$domain" \
 	| sed -e "s/,/\n/g" \
+	| sed -e "s/$domain/$new_domain/" \
 	| sed -e "s/^$new_domain$//g" \
 	| sed -e "/^$/d" \
 	| sed -e ':a;N;$!ba;s/\n/,/g')
 
 # Updating domain alias
-if [ "$ALIAS" != "$new_alias" ]; then
+if [ -n "$ALIAS" ] && [ "$ALIAS" != "$new_alias" ]; then
 	sed -i "s/ALIAS='$ALIAS'/ALIAS='$new_alias'/" $USER_DATA/web.conf
 fi
 

+ 5 - 5
bin/v-list-access-keys

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: list all API access keys
-# options: [FORMAT]
+# options: [USER] [FORMAT]
 #
 # example: v-list-access-keys json
 
@@ -8,10 +8,6 @@
 #                Variables & Functions                     #
 #----------------------------------------------------------#
 
-# Argument definition
-user="$1"
-format="${2:-shell}"
-
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf
 source /etc/hestiacp/hestia.conf
@@ -20,6 +16,10 @@ source $HESTIA/func/main.sh
 # load config file
 source_conf "$HESTIA/conf/hestia.conf"
 
+# Argument definition
+user="$1"
+format="${2:-shell}"
+
 # JSON list function
 json_list() {
 	echo -n '{'

+ 5 - 5
bin/v-update-user-counters

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: update user usage counters
-# options: USER
+# options: [USER]
 #
 # example: v-update-user-counters admin
 #
@@ -10,9 +10,6 @@
 #                Variables & Functions                     #
 #----------------------------------------------------------#
 
-# Argument definition
-user=$1
-
 # Includes
 # shellcheck source=/etc/hestiacp/hestia.conf
 source /etc/hestiacp/hestia.conf
@@ -21,11 +18,14 @@ source $HESTIA/func/main.sh
 # load config file
 source_conf "$HESTIA/conf/hestia.conf"
 
+# Argument definition
+user=$1
+
 #----------------------------------------------------------#
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '0' "$#" 'USER'
+check_args '0' "$#" '[USER]'
 if [ -n "$user" ]; then
 	is_format_valid 'user'
 	is_object_valid 'user' 'USER' "$user"

+ 5 - 5
bin/v-update-user-stats

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: update user statistics
-# options: USER
+# options: [USER]
 #
 # example: v-update-user-stats admin
 #
@@ -10,9 +10,6 @@
 #                Variables & Functions                     #
 #----------------------------------------------------------#
 
-# Argument definition
-user=$1
-
 # Importing system environment  as we run this script
 #       mostly by cron wich not read it by itself
 source /etc/profile.d/hestia.sh
@@ -27,11 +24,14 @@ source $HESTIA/func/domain.sh
 # load config file
 source_conf "$HESTIA/conf/hestia.conf"
 
+# Argument definition
+user=$1
+
 #----------------------------------------------------------#
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '0' "$#" 'USER'
+check_args '0' "$#" '[USER]'
 if [ ! -z "$user" ]; then
 	is_format_valid 'user'
 	is_object_valid 'user' 'USER' "$user"

+ 4 - 8
docs/_data/team.js

@@ -25,15 +25,11 @@ const globeIcon = {
 /** @type {import("vitepress").DefaultTheme.TeamMember[]} */
 export const teamMembers = [
 	{
-		avatar: 'https://www.github.com/jakobbouchard.png',
-		name: 'Jakob Bouchard 🇨🇦',
-		title: 'Developer',
-		org: 'Prosomo',
-		orgLink: 'https://prosomo.com',
+		avatar: 'https://www.github.com/imjuniper.png',
+		name: 'Juniper Bouchard 🇨🇦',
 		links: [
-			{ icon: 'github', link: 'https://github.com/jakobbouchard' },
-			{ icon: 'linkedin', link: 'https://www.linkedin.com/in/jakobbouchard' },
-			{ icon: globeIcon, link: 'https://jakobbouchard.dev' },
+			{ icon: 'github', link: 'https://github.com/imjuniper' },
+			{ icon: globeIcon, link: 'https://imjuniper.fyi' },
 		],
 	},
 	{

+ 2 - 2
docs/docs/community/hestia-nginx-cache.md

@@ -1,7 +1,7 @@
 # Hestia Nginx Cache
 
-By [Jakob Bouchard](https://github.com/jakobbouchard/)  
-[View the project](https://wordpress.org/plugins/hestia-nginx-cache/) – [Source code](https://github.com/jakobbouchard/hestia-nginx-cache)
+By [Juniper Bouchard](https://github.com/imjuniper/)  
+[View the project](https://wordpress.org/plugins/hestia-nginx-cache/) – [Source code](https://github.com/imjuniper/hestia-nginx-cache)
 
 ::: info
 Requires **Hestia >= 1.6.0**, as it uses the latest API.

+ 1 - 1
docs/docs/server-administration/email.md

@@ -64,7 +64,7 @@ When you are done you can check the configuration via [MXToolBox](https://mxtool
 1. Fill in the form and verify your email address by via the link in the email you recive.
 1. Once logged, go to Products → DQS and you will see your Query Key and below you will see the exactly fqdn that you will need to use Zen Spamhaus black list. Something like: `HereYourQueryKey.zen.dq.spamhaus.net`
 1. Edit /etc/exim4/dnsbl.conf and replace `zen.spamhaus.org` with `HereYourQueryKey.zen.dq.spamhaus.net`
-1. Also edit /etc/exim4/exim4.conf.template on the line: `deny    message       = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text` to `deny    message       = Rejected because $sender_host_address is in a black list` to prevent your Query key from leaking
+1. Also edit /etc/exim4/exim4.conf.template on the line: `deny    message       = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text` to `deny    message       = Rejected because $sender_host_address is in a black list at ${if match{$dnslist_domain}{.*zen.dq.spamhaus.*}{zen.dq.spamhaus.net}{$dnslist_domain}}\n$dnslist_text` to prevent your Query key from leaking
 1. Restart exim4 with systemctl restart exim4
 
 ## How do I disable internal lookup for email

+ 7 - 7
func/backup.sh

@@ -13,7 +13,7 @@ local_backup() {
 	rm -f $BACKUP/$user.$backup_new_date.tar
 
 	# Checking retention
-	backup_list=$(ls -lrt $BACKUP/ | awk '{print $9}' | grep "^$user\." | grep ".tar")
+	backup_list=$(ls -lrt $BACKUP/ | awk '{print $9}' | grep "^$user\." | grep ".tar" | sort)
 	backups_count=$(echo "$backup_list" | wc -l)
 	if [ "$BACKUPS" -le "$backups_count" ]; then
 		backups_rm_number=$((backups_count - BACKUPS + 1))
@@ -126,9 +126,9 @@ ftp_backup() {
 
 	# Checking retention (Only include .tar files)
 	if [ -z $BPATH ]; then
-		backup_list=$(ftpc "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar")
+		backup_list=$(ftpc "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar" | sort)
 	else
-		backup_list=$(ftpc "cd $BPATH" "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar")
+		backup_list=$(ftpc "cd $BPATH" "ls" | awk '{print $9}' | grep "^$user\." | grep ".tar" | sort)
 	fi
 	backups_count=$(echo "$backup_list" | wc -l)
 	if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -401,9 +401,9 @@ sftp_backup() {
 
 	# Checking retention (Only include .tar files)
 	if [ -z $BPATH ]; then
-		backup_list=$(sftpc "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar")
+		backup_list=$(sftpc "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar" | sort)
 	else
-		backup_list=$(sftpc "cd $BPATH" "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar")
+		backup_list=$(sftpc "cd $BPATH" "ls -l" | awk '{print $9}' | grep "^$user\." | grep ".tar" | sort)
 	fi
 	backups_count=$(echo "$backup_list" | wc -l)
 	if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -524,7 +524,7 @@ rclone_backup() {
 		fi
 
 		# Only include *.tar files
-		backup_list=$(rclone lsf $HOST: | cut -d' ' -f1 | grep "^$user\." | grep ".tar")
+		backup_list=$(rclone lsf $HOST: | cut -d' ' -f1 | grep "^$user\." | grep ".tar" | sort)
 		backups_count=$(echo "$backup_list" | wc -l)
 		backups_rm_number=$((backups_count - BACKUPS))
 		if [ "$backups_count" -ge "$BACKUPS" ]; then
@@ -540,7 +540,7 @@ rclone_backup() {
 		fi
 
 		# Only include *.tar files
-		backup_list=$(rclone lsf $HOST:$BPATH | cut -d' ' -f1 | grep "^$user\." | grep ".tar")
+		backup_list=$(rclone lsf $HOST:$BPATH | cut -d' ' -f1 | grep "^$user\." | grep ".tar" | sort)
 		backups_count=$(echo "$backup_list" | wc -l)
 		backups_rm_number=$(($backups_count - $BACKUPS))
 		if [ "$backups_count" -ge "$BACKUPS" ]; then

+ 18 - 7
func/domain.sh

@@ -432,10 +432,8 @@ is_web_domain_cert_valid() {
 	fi
 
 	if [ -e "$ssl_dir/$domain.ca" ]; then
-		s1=$(openssl x509 -text -in $ssl_dir/$domain.crt 2> /dev/null)
-		s1=$(echo "$s1" | grep Issuer | awk -F = '{print $6}' | head -n1)
-		s2=$(openssl x509 -text -in $ssl_dir/$domain.ca 2> /dev/null)
-		s2=$(echo "$s2" | grep Subject | awk -F = '{print $6}' | head -n1)
+		s1=$(openssl x509 -noout -in $ssl_dir/$domain.crt -issuer 2> /dev/null | cut -d = -f2-)
+		s2=$(openssl x509 -noout -in $ssl_dir/$domain.ca -subject 2> /dev/null | cut -d = -f2-)
 		if [ "$s1" != "$s2" ]; then
 			check_result "$E_NOTEXIST" "SSL intermediate chain is not valid"
 		fi
@@ -497,19 +495,32 @@ update_domain_zone() {
 		SERIAL=$(date +'%Y%m%d01')
 	fi
 	if [[ "$domain" = *[![:ascii:]]* ]]; then
-		domain_idn=$(idn2 --quiet $domain)
+		domain_idn=$(idn2 --quiet "$domain")
 	else
 		domain_idn=$domain
 	fi
+
+	# Set SOA refresh value based on TLD
+	tld="${domain_idn##*.}"
+	case "$tld" in
+		de | cz | pl | pt)
+			refresh=1800
+			;;
+		*)
+			refresh=3600
+			;;
+	esac
+
 	zn_conf="$HOMEDIR/$user/conf/dns/$domain.db"
-	echo "\$TTL $TTL
+	echo "\$TTL $zone_ttl
 @    IN    SOA    $SOA.    root.$domain_idn. (
                                             $SERIAL
                                             7200
-                                            3600
+                                            $refresh
                                             1209600
                                             180 )
 " > $zn_conf
+
 	fields='$RECORD\t$TTL\tIN\t$TYPE\t$PRIORITY\t$VALUE'
 	while read line; do
 		unset TTL

+ 5 - 4
func/main.sh

@@ -403,8 +403,8 @@ parse_object_kv_list() {
 
 # Check if object is supended
 is_object_suspended() {
-	if [ $2 = 'USER' ]; then
-		spnd=$(cat $USER_DATA/$1.conf | grep "SUSPENDED='yes'")
+	if [ "$2" = 'USER' ]; then
+		spnd=$(grep "SUSPENDED='yes'" $USER_DATA/$1.conf)
 	else
 		spnd=$(grep "$2='$3'" $USER_DATA/$1.conf | grep "SUSPENDED='yes'")
 	fi
@@ -816,7 +816,7 @@ is_ip46_format_valid() {
 
 is_ipv4_cidr_format_valid() {
 	object_name=${2-ip}
-	valid=$($HESTIA_PHP -r '$cidr="$argv[1]"; list($ip, $netmask) = [...explode("/", $cidr), 32]; echo ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && $netmask <= 32) ? 0 : 1);' $1)
+	valid=$($HESTIA_PHP -r '[$ip, $net] = [...explode("/", $argv[1]), "32"]; echo (preg_match("/^(\d{1,3}\.){3}\d{1,3}$/", $ip) && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && is_numeric($net) && $net >= 0 && $net <= 32) ? 0 : 1;' "$1")
 	if [ "$valid" -ne 0 ]; then
 		check_result "$E_INVALID" "invalid $object_name :: $1"
 	fi
@@ -1621,7 +1621,8 @@ format_no_quotes() {
 }
 
 is_username_format_valid() {
-	if [[ ! "$1" =~ ^[A-Za-z0-9._%+-]+@[[:alnum:].-]+\.[A-Za-z]{2,63}$ ]]; then
+	if [[ ! "$1" =~ ^[A-Za-z0-9._%+-]+@[[:alnum:].-]+\.[A-Za-z]{2,63}$ ]] \
+		&& [[ ! "$1" =~ ^[A-Za-z0-9._%+-]+(/|\\)[A-Za-z0-9._%+-]+$ ]]; then
 		is_string_format_valid "$1" "$2"
 	fi
 }

+ 28 - 29
install/deb/filemanager/filegator/dist/css/hst-custom.css

@@ -74,12 +74,12 @@ html {
 
 /* ------------------------------ */
 
-#single-actions[data-v-0e9ddddb] {
+#single-actions:not([data-v]) {
 	padding: 0 !important;
 }
 
-#multi-actions a[data-v-0e9ddddb],
-#multi-actions .upload a[data-v-0e9ddddb] {
+#multi-actions a:not([data-v]),
+#multi-actions .upload a:not([data-v]) {
 	background: #fff !important;
 	padding: 3px 11px !important;
 	border-radius: 6px !important;
@@ -87,57 +87,57 @@ html {
 	border: 1px solid #26232c26 !important;
 }
 
-#multi-actions a[data-v-0e9ddddb]:hover {
+#multi-actions a:not([data-v]):hover {
 	background: #343b44 !important;
 	color: #fff !important;
 }
 
-#multi-actions .upload a[data-v-0e9ddddb] {
+#multi-actions .upload a:not([data-v]) {
 	background: #343b44 !important;
 	color: #fff !important;
 }
 
-#multi-actions .upload a[data-v-0e9ddddb]:hover {
+#multi-actions .upload a:not([data-v]):hover {
 	background: #424952 !important;
 	color: #fff !important;
 }
 
-#multi-actions a[data-v-0e9ddddb] .dropdown-item {
+#multi-actions a:not([data-v]) .dropdown-item {
 	background: none !important;
 	border: none !important;
 	padding: 5px 15px !important;
 	border-radius: 0 !important;
 }
 
-#multi-actions a[data-v-0e9ddddb] .dropdown-item:hover {
+#multi-actions a:not([data-v]) .dropdown-item:hover {
 	background: #f5f5f5 !important;
 	color: #343434 !important;
 }
 
 @media (prefers-color-scheme: dark) {
-	#multi-actions a[data-v-0e9ddddb] {
+	#multi-actions a:not([data-v]) {
 		background: #222 !important;
 		color: #fff !important;
 		border: 1px solid #222 !important;
 	}
 
-	#multi-actions a[data-v-0e9ddddb]:hover {
+	#multi-actions a:not([data-v]):hover {
 		background: #303030 !important;
 		color: #fff !important;
 	}
 
-	#multi-actions a[data-v-0e9ddddb] .dropdown-item:hover {
+	#multi-actions a:not([data-v]) .dropdown-item:hover {
 		background: #545454 !important;
 		color: #fff !important;
 	}
 
-	#multi-actions .upload a[data-v-0e9ddddb] {
+	#multi-actions .upload a:not([data-v]) {
 		background: #172924 !important;
 		color: #34b891 !important;
 		border: 1px solid #26232c26 !important;
 	}
 
-	#multi-actions .upload a[data-v-0e9ddddb]:hover {
+	#multi-actions .upload a:not([data-v]):hover {
 		background: #083426 !important;
 		color: #34b891 !important;
 	}
@@ -149,25 +149,25 @@ html {
 
 /* ------------------------------ */
 
-.file-row.type-dir a.name[data-v-0e9ddddb]::before,
-.file-row.type-file a.name[data-v-0e9ddddb]::before {
+.file-row.type-dir a.name:not([data-v])::before,
+.file-row.type-file a.name:not([data-v])::before {
 	/* stylelint-disable */
 	font-family: "Font Awesome 5 Free" !important;
 	/* stylelint-enable */
 }
 
-.file-row.type-dir a.name[data-v-0e9ddddb]::before {
+.file-row.type-dir a.name:not([data-v])::before {
 	content: "\f07b" !important;
 	color: #f9b30f !important;
 }
 
-.file-row.type-file a.name[data-v-0e9ddddb]::before {
+.file-row.type-file a.name:not([data-v])::before {
 	content: "\f15c" !important;
 	color: #363636 !important;
 }
 
 @media (prefers-color-scheme: dark) {
-	.file-row.type-file a.name[data-v-0e9ddddb]::before {
+	.file-row.type-file a.name:not([data-v])::before {
 		color: #cbcbcb !important;
 	}
 }
@@ -178,20 +178,20 @@ html {
 
 /* ------------------------------ */
 
-.breadcrumb a[data-v-0e9ddddb],
+.breadcrumb a:not([data-v]),
 .breadcrumb li + li::before {
 	font-weight: 400 !important;
 	padding: 1px 6px !important;
 	border-radius: 5px !important;
 }
 
-.breadcrumb a[data-v-0e9ddddb] {
+.breadcrumb a:not([data-v]) {
 	background: #fff !important;
 	color: #343b44 !important;
 	border: 1px solid #00000017 !important;
 }
 
-.breadcrumb a[data-v-0e9ddddb]:hover {
+.breadcrumb a:not([data-v]):hover {
 	background: #343b44 !important;
 	color: #fff !important;
 }
@@ -203,13 +203,13 @@ html {
 }
 
 @media (prefers-color-scheme: dark) {
-	.breadcrumb a[data-v-0e9ddddb] {
+	.breadcrumb a:not([data-v]) {
 		background: #172924 !important;
 		color: #34b891 !important;
 		border: 1px solid #00000017 !important;
 	}
 
-	.breadcrumb a[data-v-0e9ddddb]:hover {
+	.breadcrumb a:not([data-v]):hover {
 		background: #083426 !important;
 		color: #34b891 !important;
 	}
@@ -284,19 +284,18 @@ html {
 	}
 }
 
-a[data-v-45d0a157],
-a[data-v-45d0a157]::before {
-	color: #373737 !important;
+.tree-list a:not([data-v]),
+a:not([data-v])::before {
 	font-weight: 700 !important;
 	padding: 4px 6px !important;
 	border-radius: 5px !important;
 }
 
-a[data-v-45d0a157]:hover {
+.tree-list a:not([data-v]):hover {
 	background: #efefef !important;
 }
 
-a[data-v-45d0a157]::before {
+.tree-list a:not([data-v])::before {
 	content: "\f07b" !important;
 	/* stylelint-disable */
 	font-family: "Font Awesome 5 Free" !important;
@@ -305,7 +304,7 @@ a[data-v-45d0a157]::before {
 }
 
 @media (prefers-color-scheme: dark) {
-	a[data-v-45d0a157]:hover {
+	.tree-list a:not([data-v]):hover {
 		background: #282828 !important;
 	}
 }

+ 4 - 0
install/deb/templates/mail/nginx/default.stpl

@@ -30,6 +30,8 @@ server {
 
 		try_files $uri $uri/ =404;
 
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 
 		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ {
@@ -39,6 +41,8 @@ server {
 	}
 
 	location @fallback {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 	}
 

+ 2 - 0
install/deb/templates/mail/nginx/default_disabled.stpl

@@ -20,6 +20,8 @@ server {
 	}
 
 	location / {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass http://%ip%:%web_port%;
 	}
 

+ 4 - 0
install/deb/templates/mail/nginx/default_snappymail.stpl

@@ -30,6 +30,8 @@ server {
 
 		try_files $uri $uri/ =404;
 
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 
 		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ {
@@ -39,6 +41,8 @@ server {
 	}
 
 	location @fallback {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 	}
 

+ 4 - 0
install/deb/templates/web/nginx/caching.stpl

@@ -26,6 +26,8 @@ server {
 	}
 
 	location / {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 
 		proxy_cache %domain%;
@@ -63,6 +65,8 @@ server {
 	}
 
 	location @fallback {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 	}
 

+ 4 - 0
install/deb/templates/web/nginx/default.stpl

@@ -26,6 +26,8 @@ server {
 	}
 
 	location / {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 
 		location ~* ^.+\.(%proxy_extensions%)$ {
@@ -40,6 +42,8 @@ server {
 	}
 
 	location @fallback {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 	}
 

+ 4 - 0
install/deb/templates/web/nginx/hosting.stpl

@@ -26,6 +26,8 @@ server {
 	}
 
 	location / {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 
 		location ~* ^.+\.(%proxy_extensions%)$ {
@@ -40,6 +42,8 @@ server {
 	}
 
 	location @fallback {
+		proxy_ssl_server_name on;
+		proxy_ssl_name $host;
 		proxy_pass https://%ip%:%web_ssl_port%;
 	}
 

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/magento.stpl

@@ -168,7 +168,7 @@ server {
 	}
 
 	# PHP entry point for main application
-	location ~ (index|get|static|report|404|503)\.php$ {
+	location ~ (index|get|static|report|404|503|health_check)\.php$ {
 		try_files $uri =404;
 
 		include /etc/nginx/fastcgi_params;

+ 1 - 1
install/deb/templates/web/nginx/php-fpm/magento.tpl

@@ -156,7 +156,7 @@ server {
 	}
 
 	# PHP entry point for main application
-	location ~ (index|get|static|report|404|503)\.php$ {
+	location ~ (index|get|static|report|404|503|health_check)\.php$ {
 		try_files $uri =404;
 
 		include /etc/nginx/fastcgi_params;

+ 1 - 1
install/deb/templates/web/nginx/suspended.stpl

@@ -41,5 +41,5 @@ server {
 		alias %home%/%user%/web/%domain%/document_errors/;
 	}
 
-	include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
+	include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_lets*;
 }

+ 2 - 1
install/deb/templates/web/nginx/suspended.tpl

@@ -32,5 +32,6 @@ server {
 		alias %home%/%user%/web/%domain%/document_errors/;
 	}
 
-	include %home%/%user%/conf/web/%domain%/nginx.conf_*;
+	include %home%/%user%/conf/web/%domain%/nginx.conf_lets*;
+
 }

+ 2 - 2
install/hst-install-debian.sh

@@ -31,7 +31,7 @@ HESTIA_COMMON_DIR="$HESTIA/install/common"
 VERBOSE='no'
 
 # Define software versions
-HESTIA_INSTALL_VER='1.9.3'
+HESTIA_INSTALL_VER='1.9.4'
 # Supported PHP versions
 multiphp_v=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2" "8.3" "8.4")
 # One of the following PHP versions is required for Roundcube / phpmyadmin
@@ -44,7 +44,7 @@ mariadb_v="11.4"
 node_v="20"
 
 # Defining software pack for all distros
-software="acl apache2 apache2-suexec-custom apache2-suexec-pristine apache2-utils at awstats bc bind9 bsdmainutils bsdutils
+software="acl apache2 apache2-suexec-custom apache2-utils at awstats bc bind9 bsdmainutils bsdutils
   clamav-daemon cron curl dnsutils dovecot-imapd dovecot-managesieved dovecot-pop3d dovecot-sieve e2fslibs e2fsprogs
   exim4 exim4-daemon-heavy expect fail2ban flex ftp git hestia=${HESTIA_INSTALL_VER} hestia-nginx hestia-php hestia-web-terminal
   idn2 imagemagick ipset jq libapache2-mod-fcgid libapache2-mod-php$fpm_v libapache2-mpm-itk libmail-dkim-perl lsb-release

+ 4 - 3
install/hst-install-ubuntu.sh

@@ -31,7 +31,7 @@ HESTIA_COMMON_DIR="$HESTIA/install/common"
 VERBOSE='no'
 
 # Define software versions
-HESTIA_INSTALL_VER='1.9.3'
+HESTIA_INSTALL_VER='1.9.4'
 # Supported PHP versions
 multiphp_v=("5.6" "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "8.1" "8.2" "8.3" "8.4")
 # One of the following PHP versions is required for Roundcube / phpmyadmin
@@ -52,7 +52,7 @@ software="acl apache2 apache2.2-common apache2-suexec-custom apache2-utils appar
   php$fpm_v php$fpm_v-apcu php$fpm_v-bz2 php$fpm_v-cgi php$fpm_v-cli php$fpm_v-common php$fpm_v-curl php$fpm_v-gd
   php$fpm_v-imagick php$fpm_v-imap php$fpm_v-intl php$fpm_v-ldap php$fpm_v-mbstring php$fpm_v-mysql php$fpm_v-opcache
   php$fpm_v-pgsql php$fpm_v-pspell php$fpm_v-readline php$fpm_v-xml php$fpm_v-zip postgresql postgresql-contrib
-  proftpd-basic quota rrdtool rsyslog util-linux spamassassin
+  proftpd-core proftpd-mod-crypto quota rrdtool rsyslog util-linux spamassassin
   sysstat unzip vim-common vsftpd whois zip zstd bubblewrap restic"
 
 installer_dependencies="apt-transport-https ca-certificates curl dirmngr gnupg openssl software-properties-common wget sudo"
@@ -983,8 +983,9 @@ if [ "$vsftpd" = 'no' ]; then
 	software=$(echo "$software" | sed -e "s/vsftpd//")
 fi
 if [ "$proftpd" = 'no' ]; then
-	software=$(echo "$software" | sed -e "s/proftpd-basic//")
+	software=$(echo "$software" | sed -e "s/proftpd-core//")
 	software=$(echo "$software" | sed -e "s/proftpd-mod-vroot//")
+	software=$(echo "$software" | sed -e "s/proftpd-mod-crypto//")
 fi
 if [ "$named" = 'no' ]; then
 	software=$(echo "$software" | sed -e "s/bind9//")

+ 2 - 4
install/hst-install.sh

@@ -83,9 +83,7 @@ no_support_message() {
 	echo "Hestia Control Panel. Officially supported releases:"
 	echo "****************************************************"
 	echo "  Debian 11, 12"
-	echo "  Ubuntu 20.04, 22.04, 24.04 LTS"
-	# Commenting this out for now
-	# echo "  AlmaLinux, EuroLinux, Red Hat EnterPrise Linux, Rocky Linux 8,9"
+	echo "  Ubuntu 22.04, 24.04 LTS"
 	echo ""
 	exit 1
 }
@@ -144,7 +142,7 @@ check_wget_curl() {
 
 # Check for supported operating system before proceeding with download
 # of OS-specific installer, and throw error message if unsupported OS detected.
-if [[ "$release" =~ ^(11|12|20.04|22.04|24.04)$ ]]; then
+if [[ "$release" =~ ^(11|12|22.04|24.04)$ ]]; then
 	check_wget_curl $*
 # elif [[ -e "/etc/redhat-release" ]] && [[ "$release" =~ ^(8|9)$ ]]; then
 # 	check_wget_curl $*

+ 1 - 1
install/upgrade/upgrade.conf

@@ -50,7 +50,7 @@ pga_v='7.14.6'
 
 # Set version of RoundCube (Webmail) to update during upgrade if not already installed
 # Note: only applies to "non-apt installs >= 1.4.0 or manually phased out"
-rc_v='1.6.10'
+rc_v='1.6.11'
 
 # Set version of SnappyMail (Webmail) to update during upgrade if not already installed
 sm_v='2.38.2'

+ 32 - 0
install/upgrade/versions/1.9.4.sh

@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Hestia Control Panel upgrade script for target version 1.9.4
+
+#######################################################################################
+#######                      Place additional commands below.                   #######
+#######################################################################################
+####### upgrade_config_set_value only accepts true or false.                    #######
+#######                                                                         #######
+####### Pass through information to the end user in case of a issue or problem  #######
+#######                                                                         #######
+####### Use add_upgrade_message "My message here" to include a message          #######
+####### in the upgrade notification email. Example:                             #######
+#######                                                                         #######
+####### add_upgrade_message "My message here"                                   #######
+#######                                                                         #######
+####### You can use \n within the string to create new lines.                   #######
+#######################################################################################
+
+upgrade_config_set_value 'UPGRADE_UPDATE_WEB_TEMPLATES' 'false'
+upgrade_config_set_value 'UPGRADE_UPDATE_DNS_TEMPLATES' 'false'
+upgrade_config_set_value 'UPGRADE_UPDATE_MAIL_TEMPLATES' 'true'
+upgrade_config_set_value 'UPGRADE_REBUILD_USERS' 'no'
+upgrade_config_set_value 'UPGRADE_UPDATE_FILEMANAGER_CONFIG' 'true'
+
+if grep -q "internal-sftp-server" /etc/ssh/sshd_config; then
+	sed -i 's/Subsystem sftp internal-sftp-.*/Subsystem sftp internal-sftp/' /etc/ssh/sshd_config
+fi
+
+if grep -q "Subsystem sftp /usr/lib/sftp-server-" /etc/ssh/sshd_config; then
+	sed -i 's/Subsystem sftp \/usr\/lib\/sftp-server-.*/Subsystem sftp \/usr\/lib\/sftp-server/' /etc/ssh/sshd_config
+fi

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
 	"name": "hestia",
-	"version": "1.9.2",
+	"version": "1.9.4",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "hestia",
-			"version": "1.9.2",
+			"version": "1.9.4",
 			"hasInstallScript": true,
 			"license": "GPL-3.0-or-later",
 			"dependencies": {

+ 1 - 1
src/deb/hestia/control

@@ -1,7 +1,7 @@
 Source: hestia
 Package: hestia
 Priority: optional
-Version: 1.9.3
+Version: 1.9.4
 Section: admin
 Maintainer: HestiaCP <info@hestiacp.com>
 Homepage: https://www.hestiacp.com

+ 1 - 1
src/deb/nginx/control

@@ -1,7 +1,7 @@
 Source: hestia-nginx
 Package: hestia-nginx
 Priority: optional
-Version: 1.27.4
+Version: 1.28.0
 Section: admin
 Maintainer: HestiaCP <info@hestiacp.com>
 Homepage: https://www.hestiacp.com

+ 1 - 1
src/deb/php/control

@@ -1,7 +1,7 @@
 Source: hestia-php
 Package: hestia-php
 Priority: optional
-Version: 8.3.17
+Version: 8.3.23
 Section: admin
 Maintainer: HestaCP <info@hestiacp.com>
 Homepage: https://www.hestiacp.com

+ 6 - 2
web/edit/server/hestiaweb/index.php

@@ -17,10 +17,14 @@ if (!empty($_POST["save"])) {
 		exec("mktemp", $mktemp_output, $return_var);
 		$new_conf = $mktemp_output[0];
 		$fp = fopen($new_conf, "w");
-		fwrite($fp, str_replace("\r\n", "\n", $_POST["v_config"]));
+		$config = str_replace("\r\n", "\n", $_POST["v_config"]);
+		if (!str_ends_with($config, "\n")) {
+			$config .= "\n";
+		}
+		fwrite($fp, $config);
 		fclose($fp);
 		exec(
-			HESTIA_CMD . "v-change-sys-service-config " . $new_conf . " hestiaweb no",
+			HESTIA_CMD . "v-change-sys-service-config " . $new_conf . " hestiaweb yes",
 			$output,
 			$return_var,
 		);

BIN
web/locale/ar/LC_MESSAGES/hestiacp.mo


BIN
web/locale/az/LC_MESSAGES/hestiacp.mo


BIN
web/locale/bg/LC_MESSAGES/hestiacp.mo


BIN
web/locale/bn/LC_MESSAGES/hestiacp.mo


BIN
web/locale/bs/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ca/LC_MESSAGES/hestiacp.mo


BIN
web/locale/cs/LC_MESSAGES/hestiacp.mo


BIN
web/locale/da/LC_MESSAGES/hestiacp.mo


BIN
web/locale/de/LC_MESSAGES/hestiacp.mo


BIN
web/locale/el/LC_MESSAGES/hestiacp.mo


BIN
web/locale/es/LC_MESSAGES/hestiacp.mo


BIN
web/locale/fa/LC_MESSAGES/hestiacp.mo


BIN
web/locale/fi/LC_MESSAGES/hestiacp.mo


BIN
web/locale/fr/LC_MESSAGES/hestiacp.mo


BIN
web/locale/hr/LC_MESSAGES/hestiacp.mo


BIN
web/locale/hu/LC_MESSAGES/hestiacp.mo


BIN
web/locale/id/LC_MESSAGES/hestiacp.mo


BIN
web/locale/it/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ja/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ka/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ko/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ku/LC_MESSAGES/hestiacp.mo


BIN
web/locale/nl/LC_MESSAGES/hestiacp.mo


BIN
web/locale/no/LC_MESSAGES/hestiacp.mo


BIN
web/locale/pl/LC_MESSAGES/hestiacp.mo


BIN
web/locale/pt-br/LC_MESSAGES/hestiacp.mo


BIN
web/locale/pt/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ro/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ru/LC_MESSAGES/hestiacp.mo


BIN
web/locale/sk/LC_MESSAGES/hestiacp.mo


BIN
web/locale/sq/LC_MESSAGES/hestiacp.mo


BIN
web/locale/sr/LC_MESSAGES/hestiacp.mo


BIN
web/locale/sv/LC_MESSAGES/hestiacp.mo


BIN
web/locale/th/LC_MESSAGES/hestiacp.mo


BIN
web/locale/tr/LC_MESSAGES/hestiacp.mo


BIN
web/locale/uk/LC_MESSAGES/hestiacp.mo


BIN
web/locale/ur/LC_MESSAGES/hestiacp.mo


BIN
web/locale/vi/LC_MESSAGES/hestiacp.mo


BIN
web/locale/zh-cn/LC_MESSAGES/hestiacp.mo


BIN
web/locale/zh-tw/LC_MESSAGES/hestiacp.mo


+ 106 - 48
web/templates/includes/panel.php

@@ -15,15 +15,13 @@
 
 				<!-- Usage Statistics -->
 				<div class="top-bar-usage">
-					<?php
-						if ($_SESSION['look'] !== '') {
-							$user_icon = 'fa-binoculars';
-						} else if ($_SESSION['userContext'] === 'admin') {
-							$user_icon = 'fa-user-tie';
-						} else {
-							$user_icon = 'fa-user';
-						}
-					?>
+					<?php if ($_SESSION["look"] !== "") {
+     	$user_icon = "fa-binoculars";
+     } elseif ($_SESSION["userContext"] === "admin") {
+     	$user_icon = "fa-user-tie";
+     } else {
+     	$user_icon = "fa-user";
+     } ?>
 					<div class="top-bar-usage-inner">
 						<span class="top-bar-usage-item">
 							<i class="fas <?= $user_icon ?>" title="<?= _("Logged in as") ?>: <?= htmlspecialchars($panel[$user]["NAME"]) ?>"></i>
@@ -37,6 +35,11 @@
 								<?= humanize_usage_size($panel[$user]["U_DISK"]) ?>
 							</span>
 							<?= humanize_usage_measure($panel[$user]["U_DISK"]) ?>
+							/
+							<span class="u-text-bold">
+							<?= humanize_usage_size($panel[$user]["DISK_QUOTA"]) ?>
+							</span>
+							<?= humanize_usage_measure($panel[$user]["DISK_QUOTA"]) ?>
 						</span>
 						<span class="top-bar-usage-item">
 							<i class="fas fa-right-left" title="<?= _("Bandwidth") ?>: <?= humanize_usage_size($panel[$user]["U_BANDWIDTH"]) ?> <?= humanize_usage_measure($panel[$user]["U_BANDWIDTH"]) ?>"></i>
@@ -44,6 +47,11 @@
 								<?= humanize_usage_size($panel[$user]["U_BANDWIDTH"]) ?>
 							</span>
 							<?= humanize_usage_measure($panel[$user]["U_BANDWIDTH"]) ?>
+							/
+							<span class="u-text-bold">
+								<?= humanize_usage_size($panel[$user]["BANDWIDTH"]) ?>
+							</span>
+							<?= humanize_usage_measure($panel[$user]["BANDWIDTH"]) ?>
 						</span>
 					</div>
 				</div>
@@ -55,9 +63,9 @@
 
 				<!-- Notifications -->
 				<?php
-				$impersonatingAdmin = ($_SESSION['userContext'] === 'admin') && ($_SESSION['look'] !== '' && ($user == 'admin'));
-				// Do not show notifications panel when impersonating 'admin' user
-				if (!$impersonatingAdmin) { ?>
+    $impersonatingAdmin = $_SESSION["userContext"] === "admin" && ($_SESSION["look"] !== "" && $user == "admin");
+    // Do not show notifications panel when impersonating 'admin' user
+    if (!$impersonatingAdmin) { ?>
 					<div x-data="notifications" class="top-bar-notifications">
 						<button
 							x-on:click="toggle()"
@@ -141,7 +149,8 @@
 							</template>
 						</div>
 					</div>
-				<?php } ?>
+				<?php }
+    ?>
 
 				<!-- Menu -->
 				<nav x-data="{ open: false }" class="top-bar-menu">
@@ -161,11 +170,13 @@
 
 							<!-- File Manager -->
 							<?php if (isset($_SESSION["FILE_MANAGER"]) && !empty($_SESSION["FILE_MANAGER"]) && $_SESSION["FILE_MANAGER"] == "true") { ?>
-								<?php if ($_SESSION["userContext"] === "admin" &&  $_SESSION["look"] === "admin" && $_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes") { ?>
+								<?php if ($_SESSION["userContext"] === "admin" && $_SESSION["look"] === "admin" && $_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes") { ?>
 									<!-- Hide file manager when impersonating admin-->
 								<?php } else { ?>
 									<li class="top-bar-menu-item">
-										<a title="<?= _("File manager") ?>" class="top-bar-menu-link <?php if ($TAB == 'FM') echo 'active' ?>" href="/fm/">
+										<a title="<?= _("File manager") ?>" class="top-bar-menu-link <?php if ($TAB == "FM") {
+	echo "active";
+} ?>" href="/fm/">
 											<i class="fas fa-folder-open"></i>
 											<span class="top-bar-menu-link-label u-hide-desktop"><?= _("File manager") ?></span>
 										</a>
@@ -175,11 +186,13 @@
 
 							<!-- Web Terminal -->
 							<?php if (isset($_SESSION["WEB_TERMINAL"]) && !empty($_SESSION["WEB_TERMINAL"]) && $_SESSION["WEB_TERMINAL"] == "true") { ?>
-								<?php if ($_SESSION["userContext"] === "admin" &&  $_SESSION["look"] === "admin" && $_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes") { ?>
+								<?php if ($_SESSION["userContext"] === "admin" && $_SESSION["look"] === "admin" && $_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes") { ?>
 									<!-- Hide web terminal when impersonating admin -->
-								<?php } else if ($_SESSION["login_shell"] != "nologin") { ?>
+								<?php } elseif ($_SESSION["login_shell"] != "nologin") { ?>
 									<li class="top-bar-menu-item">
-										<a title="<?= _("Web terminal") ?>" class="top-bar-menu-link <?php if ($TAB == 'TERMINAL') echo 'active' ?>" href="/list/terminal/">
+										<a title="<?= _("Web terminal") ?>" class="top-bar-menu-link <?php if ($TAB == "TERMINAL") {
+	echo "active";
+} ?>" href="/list/terminal/">
 											<i class="fas fa-terminal"></i>
 											<span class="top-bar-menu-link-label u-hide-desktop"><?= _("Web terminal") ?></span>
 										</a>
@@ -189,11 +202,13 @@
 
 							<!-- Server Settings -->
 							<?php if (($_SESSION["userContext"] === "admin" && $_SESSION["POLICY_SYSTEM_HIDE_SERVICES"] !== "yes") || $_SESSION["user"] === "admin") { ?>
-								<?php if ($_SESSION["userContext"] === "admin" && $_SESSION["look"] !== '') { ?>
+								<?php if ($_SESSION["userContext"] === "admin" && $_SESSION["look"] !== "") { ?>
 									<!-- Hide 'Server Settings' button when impersonating 'admin' or other users -->
 								<?php } else { ?>
 									<li class="top-bar-menu-item">
-										<a title="<?= _("Server settings") ?>" class="top-bar-menu-link <?php if (in_array($TAB, ['SERVER', 'IP', 'RRD', 'FIREWALL'])) echo 'active' ?>" href="/list/server/">
+										<a title="<?= _("Server settings") ?>" class="top-bar-menu-link <?php if (in_array($TAB, ["SERVER", "IP", "RRD", "FIREWALL"])) {
+	echo "active";
+} ?>" href="/list/server/">
 											<i class="fas fa-gear"></i>
 											<span class="top-bar-menu-link-label u-hide-desktop"><?= _("Server settings") ?></span>
 										</a>
@@ -202,10 +217,12 @@
 							<?php } ?>
 
 							<!-- Edit User -->
-							<?php if ($_SESSION["userContext"] === "admin" && ($_SESSION["look"] !== '' && $user == "admin")) { ?>
+							<?php if ($_SESSION["userContext"] === "admin" && ($_SESSION["look"] !== "" && $user == "admin")) { ?>
 								<!-- Hide 'edit user' entry point from other administrators for default 'admin' account-->
 								<li class="top-bar-menu-item">
-									<a title="<?= _("Logs") ?>" class="top-bar-menu-link <?php if ($TAB == 'LOG') echo 'active' ?>" href="/list/log/">
+									<a title="<?= _("Logs") ?>" class="top-bar-menu-link <?php if ($TAB == "LOG") {
+	echo "active";
+} ?>" href="/list/log/">
 										<i class="fas fa-clock-rotate-left"></i>
 										<span class="top-bar-menu-link-label u-hide-desktop"><?= _("Logs") ?></span>
 									</a>
@@ -223,13 +240,14 @@
 
 							<!-- Statistics -->
 							<li class="top-bar-menu-item">
-								<a title="<?= _("Statistics") ?>" class="top-bar-menu-link <?php if ($TAB == 'STATS') echo 'active' ?>" href="/list/stats/">
+								<a title="<?= _("Statistics") ?>" class="top-bar-menu-link <?php if ($TAB == "STATS") {
+	echo "active";
+} ?>" href="/list/stats/">
 									<i class="fas fa-chart-line"></i>
 									<span class="top-bar-menu-link-label u-hide-desktop"><?= _("Statistics") ?></span>
 								</a>
 							</li>
-							<?php if ( $_SESSION['HIDE_DOCS'] !== 'yes'){
-							?>
+							<?php if ($_SESSION["HIDE_DOCS"] !== "yes") { ?>
 								<!-- Help / Documentation -->
 								<li class="top-bar-menu-item">
 									<a title="<?= _("Help") ?>" class="top-bar-menu-link" href="https://hestiacp.com/docs/" target="_blank" rel="noopener">
@@ -278,16 +296,16 @@
 			<ul x-cloak x-show="open" class="main-menu-list">
 
 				<!-- Users tab -->
-				<?php if (($_SESSION['userContext'] == 'admin') && ($_SESSION['look'] === '')) { ?>
-					<?php
-						if (($_SESSION['user'] !== 'admin') && ($_SESSION['POLICY_SYSTEM_HIDE_ADMIN'] === 'yes')) {
-							$user_count = $panel[$user]['U_USERS'] - 1;
-						} else {
-							$user_count = $panel[$user]['U_USERS'];
-						}
-					?>
+				<?php if ($_SESSION["userContext"] == "admin" && $_SESSION["look"] === "") { ?>
+					<?php if ($_SESSION["user"] !== "admin" && $_SESSION["POLICY_SYSTEM_HIDE_ADMIN"] === "yes") {
+     	$user_count = $panel[$user]["U_USERS"] - 1;
+     } else {
+     	$user_count = $panel[$user]["U_USERS"];
+     } ?>
 					<li class="main-menu-item">
-						<a class="main-menu-item-link <?php if (in_array($TAB, ['USER', 'LOG'])) echo 'active' ?>" href="/list/user/" title="<?= _("Users") ?>: <?= $user_count;?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_USERS'] ?>">
+						<a class="main-menu-item-link <?php if (in_array($TAB, ["USER", "LOG"])) {
+      	echo "active";
+      } ?>" href="/list/user/" title="<?= _("Users") ?>: <?= $user_count ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_USERS"] ?>">
 							<p class="main-menu-item-label"><?= _("USER") ?><i class="fas fa-users"></i></p>
 							<ul class="main-menu-stats">
 								<li>
@@ -305,14 +323,24 @@
 				<?php if (isset($_SESSION["WEB_SYSTEM"]) && !empty($_SESSION["WEB_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["WEB_DOMAINS"] != "0") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'WEB') echo 'active' ?>" href="/list/web/" title="<?= _("Domains") ?>: <?= $panel[$user]['U_WEB_DOMAINS'] ?>&#13;<?= _("Aliases") ?>: <?= $panel[$user]['U_WEB_ALIASES'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['WEB_DOMAINS']=='unlimited' ? "∞" : $panel[$user]['WEB_DOMAINS'] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_WEB'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "WEB") {
+       	echo "active";
+       } ?>" href="/list/web/" title="<?= _("Domains") ?>: <?= $panel[$user]["U_WEB_DOMAINS"] ?>&#13;<?= _("Aliases") ?>: <?= $panel[$user]["U_WEB_ALIASES"] ?>&#13;<?= _("Limit") ?>: <?= $panel[
+	$user
+]["WEB_DOMAINS"] == "unlimited"
+	? "∞"
+	: $panel[$user]["WEB_DOMAINS"] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_WEB"] ?>">
 								<p class="main-menu-item-label"><?= _("WEB") ?><i class="fas fa-earth-americas"></i></p>
 								<ul class="main-menu-stats">
 									<li>
-										<?= _("Domains") ?>: <?= $panel[$user]["U_WEB_DOMAINS"] ?> / <?= $panel[$user]["WEB_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["WEB_DOMAINS"] ?> (<?= $panel[$user]["SUSPENDED_WEB"] ?>)
+										<?= _("Domains") ?>: <?= $panel[$user]["U_WEB_DOMAINS"] ?> / <?= $panel[$user]["WEB_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["WEB_DOMAINS"] ?> (<?= $panel[
+ 	$user
+ ]["SUSPENDED_WEB"] ?>)
 									</li>
 									<li>
-										<?= _("Aliases") ?>: <?= $panel[$user]["U_WEB_ALIASES"] ?> / <?= $panel[$user]["WEB_ALIASES"] == "unlimited" || $panel[$user]["WEB_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["WEB_ALIASES"] * $panel[$user]["WEB_DOMAINS"] ?>
+										<?= _("Aliases") ?>: <?= $panel[$user]["U_WEB_ALIASES"] ?> / <?= $panel[$user]["WEB_ALIASES"] == "unlimited" || $panel[$user]["WEB_DOMAINS"] == "unlimited"
+ 	? "<span class=\"u-text-bold\">∞</span>"
+ 	: $panel[$user]["WEB_ALIASES"] * $panel[$user]["WEB_DOMAINS"] ?>
 									</li>
 								</ul>
 							</a>
@@ -324,14 +352,22 @@
 				<?php if (isset($_SESSION["DNS_SYSTEM"]) && !empty($_SESSION["DNS_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["DNS_DOMAINS"] != "0") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'DNS') echo 'active' ?>" href="/list/dns/" title="<?= _("Domains") ?>: <?= $panel[$user]['U_DNS_DOMAINS'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['DNS_DOMAINS']=='unlimited' ? "∞" : $panel[$user]['DNS_DOMAINS'] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_DNS'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "DNS") {
+       	echo "active";
+       } ?>" href="/list/dns/" title="<?= _("Domains") ?>: <?= $panel[$user]["U_DNS_DOMAINS"] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]["DNS_DOMAINS"] == "unlimited"
+	? "∞"
+	: $panel[$user]["DNS_DOMAINS"] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_DNS"] ?>">
 								<p class="main-menu-item-label"><?= _("DNS") ?><i class="fas fa-book-atlas"></i></p>
 								<ul class="main-menu-stats">
 									<li>
-										<?= _("Zones") ?>: <?= $panel[$user]["U_DNS_DOMAINS"] ?> / <?= $panel[$user]["DNS_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["DNS_DOMAINS"] ?> (<?= $panel[$user]["SUSPENDED_DNS"] ?>)
+										<?= _("Zones") ?>: <?= $panel[$user]["U_DNS_DOMAINS"] ?> / <?= $panel[$user]["DNS_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["DNS_DOMAINS"] ?> (<?= $panel[
+ 	$user
+ ]["SUSPENDED_DNS"] ?>)
 									</li>
 									<li>
-										<?= _("Records") ?>: <?= $panel[$user]["U_DNS_RECORDS"] ?> / <?= $panel[$user]["DNS_RECORDS"] == "unlimited" || $panel[$user]["DNS_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["DNS_RECORDS"] * $panel[$user]["DNS_DOMAINS"] ?>
+										<?= _("Records") ?>: <?= $panel[$user]["U_DNS_RECORDS"] ?> / <?= $panel[$user]["DNS_RECORDS"] == "unlimited" || $panel[$user]["DNS_DOMAINS"] == "unlimited"
+ 	? "<span class=\"u-text-bold\">∞</span>"
+ 	: $panel[$user]["DNS_RECORDS"] * $panel[$user]["DNS_DOMAINS"] ?>
 									</li>
 								</ul>
 							</a>
@@ -343,14 +379,22 @@
 				<?php if (isset($_SESSION["MAIL_SYSTEM"]) && !empty($_SESSION["MAIL_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["MAIL_DOMAINS"] != "0") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'MAIL') echo 'active' ?>" href="/list/mail/" title="<?= _("Domains") ?>: <?= $panel[$user]['U_MAIL_DOMAINS'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['MAIL_DOMAINS']=='unlimited' ? "∞" : $panel[$user]['MAIL_DOMAINS'] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_MAIL'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "MAIL") {
+       	echo "active";
+       } ?>" href="/list/mail/" title="<?= _("Domains") ?>: <?= $panel[$user]["U_MAIL_DOMAINS"] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]["MAIL_DOMAINS"] == "unlimited"
+	? "∞"
+	: $panel[$user]["MAIL_DOMAINS"] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_MAIL"] ?>">
 								<p class="main-menu-item-label"><?= _("MAIL") ?><i class="fas fa-envelopes-bulk"></i></p>
 								<ul class="main-menu-stats">
 									<li>
-										<?= _("Domains") ?>: <?= $panel[$user]["U_MAIL_DOMAINS"] ?> / <?= $panel[$user]["MAIL_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["MAIL_DOMAINS"] ?> (<?= $panel[$user]["SUSPENDED_MAIL"] ?>)
+										<?= _("Domains") ?>: <?= $panel[$user]["U_MAIL_DOMAINS"] ?> / <?= $panel[$user]["MAIL_DOMAINS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["MAIL_DOMAINS"] ?> (<?= $panel[
+ 	$user
+ ]["SUSPENDED_MAIL"] ?>)
 									</li>
 									<li>
-										<?= _("Accounts") ?>: <?= $panel[$user]['U_MAIL_ACCOUNTS'] ?> / <?= $panel[$user]['MAIL_ACCOUNTS']=='unlimited' || $panel[$user]['MAIL_DOMAINS']=='unlimited' ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]['MAIL_ACCOUNTS'] * $panel[$user]['MAIL_DOMAINS'] ?>
+										<?= _("Accounts") ?>: <?= $panel[$user]["U_MAIL_ACCOUNTS"] ?> / <?= $panel[$user]["MAIL_ACCOUNTS"] == "unlimited" || $panel[$user]["MAIL_DOMAINS"] == "unlimited"
+ 	? "<span class=\"u-text-bold\">∞</span>"
+ 	: $panel[$user]["MAIL_ACCOUNTS"] * $panel[$user]["MAIL_DOMAINS"] ?>
 									</li>
 								</ul>
 							</a>
@@ -362,11 +406,17 @@
 				<?php if (isset($_SESSION["DB_SYSTEM"]) && !empty($_SESSION["DB_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["DATABASES"] != "0") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'DB') echo 'active' ?>" href="/list/db/" title="<?= _("Databases") ?>: <?= $panel[$user]['U_DATABASES'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['DATABASES']=='unlimited' ? "∞" : $panel[$user]['DATABASES'] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_DB'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "DB") {
+       	echo "active";
+       } ?>" href="/list/db/" title="<?= _("Databases") ?>: <?= $panel[$user]["U_DATABASES"] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]["DATABASES"] == "unlimited"
+	? "∞"
+	: $panel[$user]["DATABASES"] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_DB"] ?>">
 								<p class="main-menu-item-label"><?= _("DB") ?><i class="fas fa-database"></i></p>
 								<ul class="main-menu-stats">
 									<li>
-										<?= _("Databases") ?>: <?= $panel[$user]["U_DATABASES"] ?> / <?= $panel[$user]["DATABASES"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["DATABASES"] ?> (<?= $panel[$user]["SUSPENDED_DB"] ?>)
+										<?= _("Databases") ?>: <?= $panel[$user]["U_DATABASES"] ?> / <?= $panel[$user]["DATABASES"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["DATABASES"] ?> (<?= $panel[$user][
+ 	"SUSPENDED_DB"
+ ] ?>)
 									</li>
 								</ul>
 							</a>
@@ -378,11 +428,17 @@
 				<?php if (isset($_SESSION["CRON_SYSTEM"]) && !empty($_SESSION["CRON_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["CRON_JOBS"] != "0") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'CRON') echo 'active' ?>" href="/list/cron/" title="<?= _("Jobs") ?>: <?= $panel[$user]['U_WEB_DOMAINS'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['CRON_JOBS']=='unlimited' ? "∞" : $panel[$user]['CRON_JOBS'] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]['SUSPENDED_CRON'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "CRON") {
+       	echo "active";
+       } ?>" href="/list/cron/" title="<?= _("Jobs") ?>: <?= $panel[$user]["U_WEB_DOMAINS"] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]["CRON_JOBS"] == "unlimited"
+	? "∞"
+	: $panel[$user]["CRON_JOBS"] ?>&#13;<?= _("Suspended") ?>: <?= $panel[$user]["SUSPENDED_CRON"] ?>">
 								<p class="main-menu-item-label"><?= _("CRON") ?><i class="fas fa-clock"></i></p>
 								<ul class="main-menu-stats">
 									<li>
-										<?= _("Jobs") ?>: <?= $panel[$user]["U_CRON_JOBS"] ?> / <?= $panel[$user]["CRON_JOBS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["CRON_JOBS"] ?> (<?= $panel[$user]["SUSPENDED_CRON"] ?>)
+										<?= _("Jobs") ?>: <?= $panel[$user]["U_CRON_JOBS"] ?> / <?= $panel[$user]["CRON_JOBS"] == "unlimited" ? "<span class=\"u-text-bold\">∞</span>" : $panel[$user]["CRON_JOBS"] ?> (<?= $panel[$user][
+ 	"SUSPENDED_CRON"
+ ] ?>)
 									</li>
 								</ul>
 							</a>
@@ -394,7 +450,9 @@
 				<?php if (isset($_SESSION["BACKUP_SYSTEM"]) && !empty($_SESSION["BACKUP_SYSTEM"])) { ?>
 					<?php if ($panel[$user]["BACKUPS"] != "0" || $panel[$user]["U_BACKUPS"] != "0" || $panel[$user]["BACKUPS_INCREMENTAL"] == "yes") { ?>
 						<li class="main-menu-item">
-							<a class="main-menu-item-link <?php if ($TAB == 'BACKUP') echo 'active' ?>" href="/list/backup/" title="<?= _("Backups") ?>: <?= $panel[$user]['U_BACKUPS'] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]['BACKUPS']=='unlimited' ? "∞" : $panel[$user]['BACKUPS'] ?>">
+							<a class="main-menu-item-link <?php if ($TAB == "BACKUP") {
+       	echo "active";
+       } ?>" href="/list/backup/" title="<?= _("Backups") ?>: <?= $panel[$user]["U_BACKUPS"] ?>&#13;<?= _("Limit") ?>: <?= $panel[$user]["BACKUPS"] == "unlimited" ? "∞" : $panel[$user]["BACKUPS"] ?>">
 								<p class="main-menu-item-label"><?= _("BACKUP") ?><i class="fas fa-file-zipper"></i></p>
 								<ul class="main-menu-stats">
 									<li>