From 26c7874eafc76f1873d01e69d091ebb0024ed2bc Mon Sep 17 00:00:00 2001
From: Webslice <4052-webslice@users.noreply.git.ispconfig.org>
Date: Tue, 5 Mar 2019 17:53:46 +0100
Subject: [PATCH] Feature/password strength checker for aps

---
 .../lib/classes/aps_guicontroller.inc.php     |  10 ++
 interface/web/sites/lib/lang/ar_aps.lng       |   5 +
 interface/web/sites/lib/lang/bg_aps.lng       |   7 +-
 interface/web/sites/lib/lang/br_aps.lng       |   7 +-
 interface/web/sites/lib/lang/ca_aps.lng       |   7 +-
 interface/web/sites/lib/lang/cz_aps.lng       |   7 +-
 interface/web/sites/lib/lang/de_aps.lng       |   7 +-
 interface/web/sites/lib/lang/dk_aps.lng       |   5 +
 interface/web/sites/lib/lang/el_aps.lng       |   5 +
 interface/web/sites/lib/lang/en_aps.lng       |   5 +
 interface/web/sites/lib/lang/es_aps.lng       |   5 +
 interface/web/sites/lib/lang/fi_aps.lng       |   5 +
 interface/web/sites/lib/lang/fr_aps.lng       |   5 +
 interface/web/sites/lib/lang/hr_aps.lng       |   5 +
 interface/web/sites/lib/lang/hu_aps.lng       |   5 +
 interface/web/sites/lib/lang/id_aps.lng       |   5 +
 interface/web/sites/lib/lang/it_aps.lng       |   5 +
 interface/web/sites/lib/lang/ja_aps.lng       |   5 +
 interface/web/sites/lib/lang/nl_aps.lng       |   5 +
 interface/web/sites/lib/lang/pl_aps.lng       |   5 +
 interface/web/sites/lib/lang/pt_aps.lng       |   5 +
 interface/web/sites/lib/lang/ro_aps.lng       |   5 +
 interface/web/sites/lib/lang/ru_aps.lng       |   5 +
 interface/web/sites/lib/lang/se_aps.lng       |   5 +
 interface/web/sites/lib/lang/sk_aps.lng       |   5 +
 interface/web/sites/lib/lang/tr_aps.lng       |   5 +
 .../sites/templates/aps_install_package.htm   | 155 +++++++++++++-----
 27 files changed, 251 insertions(+), 49 deletions(-)

diff --git a/interface/lib/classes/aps_guicontroller.inc.php b/interface/lib/classes/aps_guicontroller.inc.php
index c895e40d0b..8a764a9c5c 100644
--- a/interface/lib/classes/aps_guicontroller.inc.php
+++ b/interface/lib/classes/aps_guicontroller.inc.php
@@ -567,6 +567,16 @@ class ApsGUIController extends ApsBase
 		}
 		else $error[] = $app->lng('error_main_domain');
 
+		if(isset($postinput['admin_password']))
+		{
+			$app->uses('validate_password');
+
+			$passwordError = $app->validate_password->password_check('', $postinput['admin_password'], '');
+			if ($passwordError) {
+				$error[] = $passwordError;
+			}
+		}
+
 		// Main location (not obligatory but must be supplied)
 		if(isset($postinput['main_location']))
 		{
diff --git a/interface/web/sites/lib/lang/ar_aps.lng b/interface/web/sites/lib/lang/ar_aps.lng
index 29fb7b6a40..881c146a4d 100644
--- a/interface/web/sites/lib/lang/ar_aps.lng
+++ b/interface/web/sites/lib/lang/ar_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Password strength';
 ?>
diff --git a/interface/web/sites/lib/lang/bg_aps.lng b/interface/web/sites/lib/lang/bg_aps.lng
index 29fb7b6a40..5313f2d910 100644
--- a/interface/web/sites/lib/lang/bg_aps.lng
+++ b/interface/web/sites/lib/lang/bg_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
-?>
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Сила на паролата';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/br_aps.lng b/interface/web/sites/lib/lang/br_aps.lng
index 6c5be1da54..46cfabfb01 100644
--- a/interface/web/sites/lib/lang/br_aps.lng
+++ b/interface/web/sites/lib/lang/br_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Atualização da lista de pacotes fina
 $wb['btn_install_txt'] = 'Instalar';
 $wb['btn_cancel_txt'] = 'Cancelar';
 $wb['limit_aps_txt'] = 'O limite de instâncias de apps para esta conta foi alcançado.';
-?>
+$wb['generate_password_txt'] = 'Gerar senha';
+$wb['repeat_password_txt'] = 'Repetir senha';
+$wb['password_mismatch_txt'] = 'A senhas não coincidem.';
+$wb['password_match_txt'] = 'A senhas coincidem.';
+$wb['password_strength_txt'] = 'Dificuldade da senha';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/ca_aps.lng b/interface/web/sites/lib/lang/ca_aps.lng
index 2c90556d66..bbf799bb39 100644
--- a/interface/web/sites/lib/lang/ca_aps.lng
+++ b/interface/web/sites/lib/lang/ca_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Mise à jour APS Packagelist terminée
 $wb['btn_install_txt'] = 'Installer';
 $wb['btn_cancel_txt'] = 'Annuler';
 $wb['limit_aps_txt'] = 'Le nombre max d\'instances APS pour votre compte a été atteint.';
-?>
+$wb['generate_password_txt'] = 'Générer un mot de passe';
+$wb['repeat_password_txt'] = 'Vérification du mot de passe';
+$wb['password_mismatch_txt'] = 'Les mots de passe ne correspondent pas.';
+$wb['password_match_txt'] = 'Les mots de passe correspondent.';
+$wb['password_strength_txt'] = 'Force du mot de passe';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/cz_aps.lng b/interface/web/sites/lib/lang/cz_aps.lng
index 5ec94945d1..36bc6816f4 100644
--- a/interface/web/sites/lib/lang/cz_aps.lng
+++ b/interface/web/sites/lib/lang/cz_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS aktualizace seznamu balíčků byl
 $wb['btn_install_txt'] = 'Instalovat';
 $wb['btn_cancel_txt'] = 'Zrušit';
 $wb['limit_aps_txt'] = 'Max. počet APS  instancí u vašeho účtu je dosaženo.';
-?>
+$wb['generate_password_txt'] = 'Generovat heslo';
+$wb['repeat_password_txt'] = 'Opakujte heslo';
+$wb['password_mismatch_txt'] = 'Hesla se neshodují.';
+$wb['password_match_txt'] = 'Hesla se shodují.';
+$wb['password_strength_txt'] = 'Bezpečnost hesla';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/de_aps.lng b/interface/web/sites/lib/lang/de_aps.lng
index aab6f4edf7..bb986b5c44 100644
--- a/interface/web/sites/lib/lang/de_aps.lng
+++ b/interface/web/sites/lib/lang/de_aps.lng
@@ -55,4 +55,9 @@ $wb['installation_success_txt'] = 'Installiert';
 $wb['installation_remove_txt'] = 'Deinstallation vorgemerkt';
 $wb['packagelist_update_finished_txt'] = 'APS Paketlistenupdate beendet.';
 $wb['limit_aps_txt'] = 'Die maximale Anzahl an APS-Instanzen für Ihr Konto wurde erreicht.';
-?>
+$wb['generate_password_txt'] = 'Passwort erzeugen';
+$wb['repeat_password_txt'] = 'Passwort wiederholen';
+$wb['password_mismatch_txt'] = 'Die Passwörter stimmen nicht überein.';
+$wb['password_match_txt'] = 'Die Passwörter stimmen überein.';
+$wb['password_strength_txt'] = 'Passwortkomplexität';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/dk_aps.lng b/interface/web/sites/lib/lang/dk_aps.lng
index 8350875354..ca006e2eb2 100644
--- a/interface/web/sites/lib/lang/dk_aps.lng
+++ b/interface/web/sites/lib/lang/dk_aps.lng
@@ -55,4 +55,9 @@ $wb['installation_success_txt'] = 'Installeret';
 $wb['installation_remove_txt'] = 'Fjernelse planlagt';
 $wb['packagelist_update_finished_txt'] = 'APS Pakke Liste opdatering er færdig.';
 $wb['limit_aps_txt'] = 'Max. antal af APS forekomster for din konto er nået.';
+$wb['generate_password_txt'] = 'Generer Adgangskode';
+$wb['repeat_password_txt'] = 'Gentage Adgangskode';
+$wb['password_mismatch_txt'] = 'Adgangskoderne stemmer ikke overens.';
+$wb['password_match_txt'] = 'Adgangskoderne stemmer overens.';
+$wb['password_strength_txt'] = 'Adgangskode styrke';
 ?>
diff --git a/interface/web/sites/lib/lang/el_aps.lng b/interface/web/sites/lib/lang/el_aps.lng
index 29fb7b6a40..0209737f61 100644
--- a/interface/web/sites/lib/lang/el_aps.lng
+++ b/interface/web/sites/lib/lang/el_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Δύναμη συνθηματικού';
 ?>
diff --git a/interface/web/sites/lib/lang/en_aps.lng b/interface/web/sites/lib/lang/en_aps.lng
index bd33c1884a..b0300fe0cc 100644
--- a/interface/web/sites/lib/lang/en_aps.lng
+++ b/interface/web/sites/lib/lang/en_aps.lng
@@ -55,4 +55,9 @@ $wb['installation_success_txt'] = 'Installed';
 $wb['installation_remove_txt'] = 'Removal planned';
 $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb["limit_aps_txt"] = 'The max. number of APS instances for your account is reached.';
+$wb["generate_password_txt"] = 'Generate Password';
+$wb["repeat_password_txt"] = 'Repeat Password';
+$wb["password_mismatch_txt"] = 'The passwords do not match.';
+$wb["password_match_txt"] = 'The passwords do match.';
+$wb["password_strength_txt"] = "Password strength";
 ?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/es_aps.lng b/interface/web/sites/lib/lang/es_aps.lng
index 7466310080..3780b32edd 100755
--- a/interface/web/sites/lib/lang/es_aps.lng
+++ b/interface/web/sites/lib/lang/es_aps.lng
@@ -55,4 +55,9 @@ $wb['supported_languages_txt'] = 'Idiomas soportados';
 $wb['supported_php_versions_txt'] = 'Versiones de PHP soportadas';
 $wb['version_txt'] = 'Versión';
 $wb['yes_txt'] = 'Sí';
+$wb['generate_password_txt'] = 'Generar contraseña';
+$wb['repeat_password_txt'] = 'Repetir contraseña';
+$wb['password_mismatch_txt'] = 'Las contraseñas no coinciden.';
+$wb['password_match_txt'] = 'Las contraseñas coinciden.';
+$wb['password_strength_txt'] = 'Fortaleza de la contraseña';
 ?>
diff --git a/interface/web/sites/lib/lang/fi_aps.lng b/interface/web/sites/lib/lang/fi_aps.lng
index 29fb7b6a40..d78701f272 100644
--- a/interface/web/sites/lib/lang/fi_aps.lng
+++ b/interface/web/sites/lib/lang/fi_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Salasanan vahvuus';
 ?>
diff --git a/interface/web/sites/lib/lang/fr_aps.lng b/interface/web/sites/lib/lang/fr_aps.lng
index 10b6edbcfd..6beef9939f 100644
--- a/interface/web/sites/lib/lang/fr_aps.lng
+++ b/interface/web/sites/lib/lang/fr_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Mise à jour APS Packagelist terminée
 $wb['btn_install_txt'] = 'Installer';
 $wb['btn_cancel_txt'] = 'Annuler';
 $wb['limit_aps_txt'] = 'Le nombre max d’instances APS pour votre compte a été atteint.';
+$wb['generate_password_txt'] = 'Générer un mot de passe';
+$wb['repeat_password_txt'] = 'Vérification du mot de passe';
+$wb['password_mismatch_txt'] = 'Les mots de passe ne correspondent pas.';
+$wb['password_match_txt'] = 'Les mots de passe correspondent.';
+$wb['password_strength_txt'] = 'Force du mot de passe';
 ?>
diff --git a/interface/web/sites/lib/lang/hr_aps.lng b/interface/web/sites/lib/lang/hr_aps.lng
index 8b2fa6450e..79d31cf7fa 100644
--- a/interface/web/sites/lib/lang/hr_aps.lng
+++ b/interface/web/sites/lib/lang/hr_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Nadogradnja APS liste paketa je završ
 $wb['btn_install_txt'] = 'Instaliraj';
 $wb['btn_cancel_txt'] = 'Odustani';
 $wb['limit_aps_txt'] = 'Iskoristili ste maksimalan broj APS instanci za vaš račun.';
+$wb['generate_password_txt'] = 'Generiraj Å¡ifru';
+$wb['repeat_password_txt'] = 'Ponovi Å¡ifru';
+$wb['password_mismatch_txt'] = 'Šifre nisu identične.';
+$wb['password_match_txt'] = 'Šifre su identične.';
+$wb['password_strength_txt'] = 'Jačina šifre';
 ?>
diff --git a/interface/web/sites/lib/lang/hu_aps.lng b/interface/web/sites/lib/lang/hu_aps.lng
index 29fb7b6a40..88708732df 100644
--- a/interface/web/sites/lib/lang/hu_aps.lng
+++ b/interface/web/sites/lib/lang/hu_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Jelszó erőssége';
 ?>
diff --git a/interface/web/sites/lib/lang/id_aps.lng b/interface/web/sites/lib/lang/id_aps.lng
index 29fb7b6a40..b8c9af2152 100644
--- a/interface/web/sites/lib/lang/id_aps.lng
+++ b/interface/web/sites/lib/lang/id_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Kekuatan Sandi';
 ?>
diff --git a/interface/web/sites/lib/lang/it_aps.lng b/interface/web/sites/lib/lang/it_aps.lng
index ced17becd3..0a6365f98f 100644
--- a/interface/web/sites/lib/lang/it_aps.lng
+++ b/interface/web/sites/lib/lang/it_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Elenco aggiornamenti APS terminato.';
 $wb['btn_install_txt'] = 'Installa';
 $wb['btn_cancel_txt'] = 'Annulla';
 $wb['limit_aps_txt'] = 'Nmero massimo di istanza APS raggiunto per il tuo account.';
+$wb['generate_password_txt'] = 'Genera Password';
+$wb['repeat_password_txt'] = 'Ripeti Password';
+$wb['password_mismatch_txt'] = 'Le password non coincidono.';
+$wb['password_match_txt'] = 'Le password coincidono.';
+$wb['password_strength_txt'] = 'Livello sicurezza Password';
 ?>
diff --git a/interface/web/sites/lib/lang/ja_aps.lng b/interface/web/sites/lib/lang/ja_aps.lng
index 29fb7b6a40..dc6b22edf7 100644
--- a/interface/web/sites/lib/lang/ja_aps.lng
+++ b/interface/web/sites/lib/lang/ja_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'パスワードの強度';
 ?>
diff --git a/interface/web/sites/lib/lang/nl_aps.lng b/interface/web/sites/lib/lang/nl_aps.lng
index 9d51f7457b..c0adacee99 100644
--- a/interface/web/sites/lib/lang/nl_aps.lng
+++ b/interface/web/sites/lib/lang/nl_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Installeren';
 $wb['btn_cancel_txt'] = 'Annuleren';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Wachtwoord sterkte';
 ?>
diff --git a/interface/web/sites/lib/lang/pl_aps.lng b/interface/web/sites/lib/lang/pl_aps.lng
index 1a2ffad688..c17bbca532 100644
--- a/interface/web/sites/lib/lang/pl_aps.lng
+++ b/interface/web/sites/lib/lang/pl_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Aktualizacja listy pakietów APS zako
 $wb['btn_install_txt'] = 'Instaluj';
 $wb['btn_cancel_txt'] = 'Anuluj';
 $wb['limit_aps_txt'] = 'Maksymalna liczba instancji APS dla Twojego konta została wyczerpana.';
+$wb['generate_password_txt'] = 'Generuj hasło';
+$wb['repeat_password_txt'] = 'Powtórz hasło';
+$wb['password_mismatch_txt'] = 'Hasła nie pasują do siebie';
+$wb['password_match_txt'] = 'Hasła pasują';
+$wb['password_strength_txt'] = 'Siła hasła';
 ?>
diff --git a/interface/web/sites/lib/lang/pt_aps.lng b/interface/web/sites/lib/lang/pt_aps.lng
index 29fb7b6a40..c17ef00914 100644
--- a/interface/web/sites/lib/lang/pt_aps.lng
+++ b/interface/web/sites/lib/lang/pt_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Dificuldade da senha';
 ?>
diff --git a/interface/web/sites/lib/lang/ro_aps.lng b/interface/web/sites/lib/lang/ro_aps.lng
index 29fb7b6a40..881c146a4d 100644
--- a/interface/web/sites/lib/lang/ro_aps.lng
+++ b/interface/web/sites/lib/lang/ro_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Password strength';
 ?>
diff --git a/interface/web/sites/lib/lang/ru_aps.lng b/interface/web/sites/lib/lang/ru_aps.lng
index f403143e59..3dd4ad0a8a 100644
--- a/interface/web/sites/lib/lang/ru_aps.lng
+++ b/interface/web/sites/lib/lang/ru_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'Обновление списка па
 $wb['btn_install_txt'] = 'Установка';
 $wb['btn_cancel_txt'] = 'Отменить';
 $wb['limit_aps_txt'] = 'Макс. количество экземпляров APS достигнуто.';
+$wb['generate_password_txt'] = 'Создать пароль';
+$wb['repeat_password_txt'] = 'Повторить пароль';
+$wb['password_mismatch_txt'] = 'Пароли не совпадают.';
+$wb['password_match_txt'] = 'Эти пароли совпадают.';
+$wb['password_strength_txt'] = 'Стойкость пароля';
 ?>
diff --git a/interface/web/sites/lib/lang/se_aps.lng b/interface/web/sites/lib/lang/se_aps.lng
index 1a21cd0fd2..3b32095d62 100644
--- a/interface/web/sites/lib/lang/se_aps.lng
+++ b/interface/web/sites/lib/lang/se_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Installera';
 $wb['btn_cancel_txt'] = 'Avbryt';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Password strength';
 ?>
diff --git a/interface/web/sites/lib/lang/sk_aps.lng b/interface/web/sites/lib/lang/sk_aps.lng
index 29fb7b6a40..d6e6c7f4ca 100644
--- a/interface/web/sites/lib/lang/sk_aps.lng
+++ b/interface/web/sites/lib/lang/sk_aps.lng
@@ -55,4 +55,9 @@ $wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.';
 $wb['btn_install_txt'] = 'Install';
 $wb['btn_cancel_txt'] = 'Cancel';
 $wb['limit_aps_txt'] = 'The max. number of APS instances for your account is reached.';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb['password_strength_txt'] = 'Pevnosť hesla';
 ?>
diff --git a/interface/web/sites/lib/lang/tr_aps.lng b/interface/web/sites/lib/lang/tr_aps.lng
index 534ee020a7..1c6ccd49a6 100644
--- a/interface/web/sites/lib/lang/tr_aps.lng
+++ b/interface/web/sites/lib/lang/tr_aps.lng
@@ -55,4 +55,9 @@ $wb['installation_success_txt'] = 'Yüklendi';
 $wb['installation_remove_txt'] = 'Kaldırma planlandı';
 $wb['packagelist_update_finished_txt'] = 'APS paket listesi güncellendi.';
 $wb['limit_aps_txt'] = 'Hesabınıza ekleyebileceğiniz en fazla APS kopyası sayısına ulaştınız.';
+$wb['generate_password_txt'] = 'Parola OluÅŸtur';
+$wb['repeat_password_txt'] = 'Parola Onayı';
+$wb['password_mismatch_txt'] = 'Parola ile onayı aynı değil.';
+$wb['password_match_txt'] = 'Parola ile onayı aynı.';
+$wb['password_strength_txt'] = 'Parola Güçlüğü';
 ?>
diff --git a/interface/web/sites/templates/aps_install_package.htm b/interface/web/sites/templates/aps_install_package.htm
index d04d671534..2c4b48b9d3 100644
--- a/interface/web/sites/templates/aps_install_package.htm
+++ b/interface/web/sites/templates/aps_install_package.htm
@@ -1,58 +1,125 @@
 <h1>
-    {tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'}
-    <span style="float:right">
-        <tmpl_if name='pkg_icon' op='!=' value=''>
-            <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> 
-        </tmpl_if>
-    </span>
+	{tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'}
+	<span style="float:right">
+		<tmpl_if name='pkg_icon' op='!=' value=''>
+			<img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" />
+		</tmpl_if>
+	</span>
 </h1>
-    
+
 <tmpl_if name='error'>
-    <div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div>
+	<div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div>
 </tmpl_if>
 
 
-        
-            <legend>{tmpl_var name='basic_settings_txt'}</legend>
-            <div class="form-group">
-                <label class="col-sm-3 control-label">{tmpl_var name='install_location_txt'}</label>
-                <div class="col-sm-9">
-				    <div class='input-group'>
+
+			<legend>{tmpl_var name='basic_settings_txt'}</legend>
+			<div class="form-group">
+				<label class="col-sm-3 control-label">{tmpl_var name='install_location_txt'}</label>
+				<div class="col-sm-9">
+					<div class='input-group'>
 						<span class='input-group-addon'>http(s)://</span>
 						<div class='input-group-field'>
 							DOMAIN_LIST_SPACE
 						</div>
 						<span class='input-group-addon'>/</span>
 						<input type="text" id="main_location" name="main_location" value="{tmpl_var name='inp_main_location'}" class="form-control" />
-                    </div>
+					</div>
 				</div>
-            </div>
+			</div>
 			<tmpl_if name='pkg_requirements_database' op='!=' value=''>
-                <div class="form-group">
-                    <label for="main_database_password" class="col-sm-3 control-label">{tmpl_var name='new_database_password_txt'}</label>
-                    <div class="col-sm-9"><input type="text" class="form-control" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" /></div></div>
-            </tmpl_if>
-                
-            PKG_SETTINGS_SPACE
-                
-            <legend>{tmpl_var name='license_txt'}</legend>
-            <div class="form-group">
-                <label for="license" class="col-sm-3 control-label">{tmpl_var name='license_txt'}</label>
-                <tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if>
-                <tmpl_if name='pkg_license_type' op='==' value='url'>
-                    <a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a>
-                    <tmpl_elseif name='pkg_license_content'>
-                        <div class="col-sm-9"><textarea class="form-control" rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea></div>
-                </tmpl_if>
-            </div>
-            <div class="form-group">
-                <label for="license" class="col-sm-3 control-label">{tmpl_var name='acceptance_txt'}</label>
-                <div class="col-sm-6"><input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if>/> &nbsp;&nbsp;{tmpl_var name='acceptance_text'}
-            </div>
-        
-            
-        <input type="hidden" name="install" value="0" />
-        <div class="clear"><div class="right">
-            <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_install_txt'}" name="btn_install" onclick="document.pageForm.install.value=1; ISPConfig.submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='btn_install_txt'}</button>
-            <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="sites/aps_availablepackages_list.php">{tmpl_var name='btn_cancel_txt'}</button>
-        </div></div>
+				<div class="form-group">
+					<label for="main_database_password" class="col-sm-3 control-label">{tmpl_var name='new_database_password_txt'}</label>
+					<div class="col-sm-9"><input type="text" class="form-control" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" /></div>
+				</div>
+			</tmpl_if>
+
+			PKG_SETTINGS_SPACE
+
+			<legend>{tmpl_var name='license_txt'}</legend>
+			<div class="form-group">
+				<label for="license" class="col-sm-3 control-label">{tmpl_var name='license_txt'}</label>
+				<tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if>
+				<tmpl_if name='pkg_license_type' op='==' value='url'>
+					<a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a>
+					<tmpl_elseif name='pkg_license_content'>
+						<div class="col-sm-9"><textarea class="form-control" rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea></div>
+				</tmpl_if>
+			</div>
+			<div class="form-group">
+				<label for="license" class="col-sm-3 control-label">{tmpl_var name='acceptance_txt'}</label>
+				<div class="col-sm-6">
+					<input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if>/> &nbsp;&nbsp;{tmpl_var name='acceptance_text'}
+				</div>
+			</div>
+
+
+		<input type="hidden" name="install" value="0" />
+		<div class="clear">
+			<div class="right">
+				<button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_install_txt'}" name="btn_install" onclick="document.pageForm.install.value=1; ISPConfig.submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='btn_install_txt'}</button>
+				<button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="sites/aps_availablepackages_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+			</div>
+		</div>
+
+		<div class="hidden" id="passwordFieldWithChecks">
+			<div class="form-group">
+				<label for="password" class="col-sm-3 control-label">{tmpl_var name='password_txt'}</label>
+				<div class="col-sm-9">
+					<div class="input-group">
+						<input type="password" name="password" id="password" value="{tmpl_var name='password'}" class="form-control" autocomplete="off" onkeyup="pass_check(this.value);checkPassMatch('password','repeat_password');" />
+						<span class="input-group-btn">
+							<button class="btn btn-default" type="button" onclick="generatePassword('password','repeat_password');">{tmpl_var name='generate_password_txt'}</button>
+						</span>
+						<p class="formHint"></p>
+					</div>
+				</div>
+			</div>
+			<div class="form-group">
+				<label class="col-sm-3 control-label">{tmpl_var name='password_strength_txt'}</label>
+				<div class="col-sm-9 checkbox">
+					<div id="passBar"></div>
+					<span id="passText">&nbsp;</span>
+				</div>
+			</div>
+			<div class="form-group">
+				<label for="repeat_password" class="col-sm-3 control-label">{tmpl_var name='repeat_password_txt'}</label>
+				<div class="col-sm-9"><input type="password" name="repeat_password" id="repeat_password" value="" class="form-control" autocomplete="off" onkeyup="checkPassMatch('password','repeat_password');" /></div></div>
+			<div class="form-group">
+				<div class="col-sm-offset-3 col-sm-9">
+					<div id="confirmpasswordError" style="display:none;" class="confirmpassworderror">{tmpl_var name='password_mismatch_txt'}</div>
+					<div id="confirmpasswordOK" style="display:none;" class="confirmpasswordok">{tmpl_var name='password_match_txt'}</div>
+				</div>
+			</div>
+		</div>
+
+		<script type="text/javascript">
+			jQuery(document).ready(function () {
+				let passwordField = jQuery('[type=password]').first();
+				if (!passwordField) {
+					return;
+				}
+
+				let passwordFieldFormGroup = passwordField.closest('.form-group');
+				let passwordFieldWithChecks = jQuery('#passwordFieldWithChecks');
+		
+				let originalLabel = passwordFieldFormGroup.find('label').first().text();
+				let originalName = passwordField.prop('name');
+				let originalMaxLength = passwordField.prop('maxlength');
+				let originalValue = passwordField.prop('value');
+				let originalFormHint = passwordField.next('.formHint').text();
+
+				let passwordFieldWithChecksInputField = passwordFieldWithChecks.find('[type=password]').first();
+				passwordFieldWithChecksInputField.prop('name', originalName);
+				passwordFieldWithChecksInputField.prop('value', originalValue);
+				passwordFieldWithChecksInputField.prop('name', originalName);
+				passwordFieldWithChecks.find('label').first().text(originalLabel);
+				passwordFieldWithChecks.find('.formHint').text(originalFormHint);
+		
+				if (originalMaxLength && originalMaxLength > 0) {
+					passwordFieldWithChecksInputField.prop('maxlength', originalMaxLength);
+				}
+
+				passwordFieldFormGroup.replaceWith(passwordFieldWithChecks.children());
+			});
+		</script>
-- 
GitLab