' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
'
' +
- '
' +
- '
',
'',
@@ -540,6 +583,23 @@ function(data) {
.click(function(e) {
e.preventDefault();
});
+ $('#confirm-no-recovery-keys').click(function(e) {
+ //e.preventDefault();
+ if ($(this).prop('checked') === true) {
+ $('#confirm-no-recovery-keys-div').addClass('alert-danger');
+ } else {
+ $('#confirm-no-recovery-keys-div').removeClass('alert-danger');
+ }
+ });
+ $('#recovery-public-key, #recovery-private-key').focusout(function(e) {
+ e.preventDefault();
+ if ($('#recovery-public-key').val() !== '' && $('#recovery-private-key').val() !== '') {
+ $('#confirm-no-recovery-keys-div').removeClass('alert-danger');
+ $('#confirm-no-recovery-keys').prop('checked', false);
+ } else {
+
+ }
+ });
// Manage click on button PERFORM
$(document).on('click', '#warningModalButtonAction', function() {
@@ -553,12 +613,14 @@ function(data) {
} else if ($('#warningModalButtonAction').attr('data-button-confirm') === 'true') {
// As reencryption relies on user's password
// ensure we have it
- if ($('#encryption-otp').val() === '') {
+ if ($('#encryption-otp').val() === '' ||
+ ($('#recovery-public-key').val() === '' || $('#recovery-private-key').val() === '') && $('#confirm-no-recovery-keys').prop('checked') === false
+ ) {
// No user password provided
$('#warningModalButtonAction')
.html('')
.attr('data-button-confirm', 'false');
-
+
} else {
// We have the password, start reencryption
$('#warningModalButtonAction')
@@ -577,6 +639,9 @@ function(data) {
'send_email_to_user': true,
'email_body': 'email_body_user_config_4',
'generate_user_new_password': false,
+ 'user_self_change': true,
+ 'recovery_public_key': $('#recovery-public-key').val(),
+ 'recovery_private_key': $('#recovery-private-key').val(),
};
$.post(
diff --git a/includes/core/teampass_ascii.txt b/includes/core/teampass_ascii.txt
new file mode 100644
index 000000000..a647cfe4c
--- /dev/null
+++ b/includes/core/teampass_ascii.txt
@@ -0,0 +1,7 @@
+
+ _____ ____
+ |_ _|__ __ _ _ __ ___ | _ \ __ _ ___ ___
+ | |/ _ \/ _` | '_ ` _ \| |_) / _` / __/ __|
+ | | __/ (_| | | | | | | __/ (_| \__ \__ \
+ |_|\___|\__,_|_| |_| |_|_| \__,_|___/___/
+
diff --git a/includes/language/bulgarian.php b/includes/language/bulgarian.php
index 30549e00c..82e311418 100755
--- a/includes/language/bulgarian.php
+++ b/includes/language/bulgarian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/catalan.php b/includes/language/catalan.php
index 7b03b627e..b2704cfca 100755
--- a/includes/language/catalan.php
+++ b/includes/language/catalan.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/chinese.php b/includes/language/chinese.php
index 0ca534de2..71bdf0482 100755
--- a/includes/language/chinese.php
+++ b/includes/language/chinese.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/czech.php b/includes/language/czech.php
index d396ba589..18edd8cc3 100755
--- a/includes/language/czech.php
+++ b/includes/language/czech.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/dutch.php b/includes/language/dutch.php
index 7485468fe..3f130d851 100755
--- a/includes/language/dutch.php
+++ b/includes/language/dutch.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/english.php b/includes/language/english.php
index e6da04bb6..addbc6a7e 100755
--- a/includes/language/english.php
+++ b/includes/language/english.php
@@ -16,6 +16,20 @@
* @see https://www.teampass.net
*/
return array(
+ 'regenerate_only_personal_items_keys' => 'Only regenerate my personal items keys (it requires your public and private keys). This will not impact shared items.',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will only regenerate key for shared items (no impact on personal ones that will become unusable).',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
'started' => 'Started',
'existing_valid_otv_links' => 'OTV valid links',
'feature_disabled_by_administrator' => 'Feature disabled by administrator',
diff --git a/includes/language/estonian.php b/includes/language/estonian.php
index 7580d5cdc..dbb59f5bb 100755
--- a/includes/language/estonian.php
+++ b/includes/language/estonian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/french.php b/includes/language/french.php
index 0df95c17a..58f1684c5 100755
--- a/includes/language/french.php
+++ b/includes/language/french.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'Liens Ă visualisation valides',
'started' => 'Lancé',
+ 'recovery_keys_not_downloaded' => 'Clés de récupération non téléchargées',
+ 'no_recovery_keys' => 'Je ne dispose pas des clés de récupération. Cette opération effacera tous les mots de passe des mes objets personnels.',
+ 'provide_recovery_keys' => 'Fournir vos clés de récupération',
+ 'public_key' => 'Clé publique',
+ 'private_key' => 'Clé privée',
+ 'download_recovery_keys' => 'Télécharger vos clés de récupération',
+ 'download_recovery_keys_confirmation' => 'Vous êtes sur le point de télécharger vos clés de récupération. Merci de les sauvegarder dans un endroit sûr.',
+ 'recovery_keys_download_date' => 'Date de téléchargement des clés de récupération',
+ 'keys_not_recovered' => 'Clés publique et privée non sauvegardées',
+ 'keys_not_recovered_explanation' => 'De façon à vous prévenir de la perte des mots de passe de vos objets personnels, vous devriez sauvegarder vos clés de récuparation.',
+ 'get_your_recovery_keys' => 'Télécharger vos clés de récupération',
+ 'keys_management' => 'Gestion des clés',
+ 'please_confirm_task_to_be_run' => 'Merci de confirmer l'exécution de la tache',
);
diff --git a/includes/language/german.php b/includes/language/german.php
index 82ba9c527..0d1558cd4 100755
--- a/includes/language/german.php
+++ b/includes/language/german.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/greek.php b/includes/language/greek.php
index d2198f14c..f2de48098 100755
--- a/includes/language/greek.php
+++ b/includes/language/greek.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/hungarian.php b/includes/language/hungarian.php
index a3c79c120..374f7b888 100755
--- a/includes/language/hungarian.php
+++ b/includes/language/hungarian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/italian.php b/includes/language/italian.php
index 5189a503b..16054112c 100755
--- a/includes/language/italian.php
+++ b/includes/language/italian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/japanese.php b/includes/language/japanese.php
index a515832c6..230804aec 100755
--- a/includes/language/japanese.php
+++ b/includes/language/japanese.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/norwegian.php b/includes/language/norwegian.php
index 585f1251a..96f565239 100755
--- a/includes/language/norwegian.php
+++ b/includes/language/norwegian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/polish.php b/includes/language/polish.php
index ebff30351..62d22069c 100755
--- a/includes/language/polish.php
+++ b/includes/language/polish.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/portuguese.php b/includes/language/portuguese.php
index aa1280d8f..67a35bc73 100755
--- a/includes/language/portuguese.php
+++ b/includes/language/portuguese.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/portuguese_br.php b/includes/language/portuguese_br.php
index 6fb2ecca5..0e3ca82e5 100755
--- a/includes/language/portuguese_br.php
+++ b/includes/language/portuguese_br.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/romanian.php b/includes/language/romanian.php
index 5fac150c8..f410278de 100755
--- a/includes/language/romanian.php
+++ b/includes/language/romanian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/russian.php b/includes/language/russian.php
index 56d06583e..7b9f5de78 100755
--- a/includes/language/russian.php
+++ b/includes/language/russian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/spanish.php b/includes/language/spanish.php
index 58000743d..58e3efb4c 100755
--- a/includes/language/spanish.php
+++ b/includes/language/spanish.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/swedish.php b/includes/language/swedish.php
index 2708c76cb..bb75efe2a 100755
--- a/includes/language/swedish.php
+++ b/includes/language/swedish.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/turkish.php b/includes/language/turkish.php
index 0341c8024..6e1924022 100755
--- a/includes/language/turkish.php
+++ b/includes/language/turkish.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/ukrainian.php b/includes/language/ukrainian.php
index f081b53e9..fd0244eb7 100755
--- a/includes/language/ukrainian.php
+++ b/includes/language/ukrainian.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/includes/language/vietnamese.php b/includes/language/vietnamese.php
index d91636534..3864851c3 100755
--- a/includes/language/vietnamese.php
+++ b/includes/language/vietnamese.php
@@ -1129,5 +1129,18 @@
'settings_otv_subdomain_tip' => 'Dedicated subdomain for onetime links. Considere your main Teampass URL as isolated from internet, this subdomain could be reachable by everyone to share this item with someone outside your organisation. From security perspective it is a lot safer with such mechanics. Note: This would requite to have a DNS entry for this subdomain pointing to your Teampass server.',
'existing_valid_otv_links' => 'OTV valid links',
'started' => 'Started',
+ 'recovery_keys_not_downloaded' => 'Recovery keys not downloaded',
+ 'no_recovery_keys' => 'I do not have recovery keys. This will clear all passwords from my personal items.',
+ 'provide_recovery_keys' => 'Provide your recovery keys',
+ 'public_key' => 'Public key',
+ 'private_key' => 'Private key',
+ 'download_recovery_keys' => 'Download your recovery keys',
+ 'download_recovery_keys_confirmation' => 'You are about to download your recovery keys. Please store them in a safe place as they should be mandatory in case of deasaster.',
+ 'recovery_keys_download_date' => 'Recovery keys download date',
+ 'keys_not_recovered' => 'Public and Private keys not stored',
+ 'keys_not_recovered_explanation' => 'In order to prevent against any passwords lost, you should store safely your personal Teampass keys',
+ 'get_your_recovery_keys' => 'Get your recovery keys',
+ 'keys_management' => 'Keys management',
+ 'please_confirm_task_to_be_run' => 'Please confirm the task to be performed',
);
diff --git a/index.php b/index.php
index 28175821a..f2d1a2776 100755
--- a/index.php
+++ b/index.php
@@ -314,6 +314,10 @@
+
+
+
+
@@ -1241,6 +1245,8 @@
+
+
...
');
@@ -1320,11 +1331,12 @@ function(data) {
userUploadedFile = false;
var data = {
- 'item_id': store.get('teampassItem').id,
- 'folder_id': selectedFolderId,
- 'access_level': store.get('teampassItem').hasAccessLevel,
+ 'item_id': itemId,
+ 'item_key': itemKey,
+ 'folder_id': folderId,
+ 'access_level': hasAccessLevel,
}
-
+ console.log(data)
// Launch action
$.post(
'sources/items.queries.php', {
@@ -1345,12 +1357,15 @@ function(data) {
timeOut: 1000
}
);
+
// Refresh tree
- refreshTree(selectedFolderId, true);
+ refreshTree(folderId, true);
// Load list of items
- ListerItems(selectedFolderId, '', 0);
+ ListerItems(folderId, '', 0);
// Close
- closeItemDetailsCard();
+ if (closeItemCard === true) {
+ closeItemDetailsCard();
+ }
} else {
// ERROR
toastr.remove();
@@ -1364,7 +1379,7 @@ function(data) {
}
}
);
- });
+ }
/**
@@ -2197,8 +2212,38 @@ function(teampassUser) {
// Load item info
Details($(this).closest('tr'), 'edit');
+ })
+ .on('click', '.list-item-clicktodelete', function(event) {
+ event.preventDefault();
+ // Delete item
+ if (debugJavascript === true) console.info('SHOW DELETE ITEM '+$(this).data('item-key'));
+
+ let $itemKey = $(this).data('item-key');
+
+ // SHow dialog
+ showModalDialogBox(
+ '#warningModal',
+ '
',
+ '',
+ '',
+ '',
+ );
+
+ // Launch deletion
+ $(document).on('click', '#warningModalButtonAction', {itemKey:$(this).data('item-key')}, function(event2) {
+ event2.preventDefault();
+ goDeleteItem(
+ '',
+ event2.data.itemKey,
+ selectedFolderId,
+ '',
+ false
+ );
+ $('#warningModal').modal('hide');
+ });
});
+
/**
* Manage mini icons on mouse over
*/
@@ -2229,10 +2274,12 @@ function(teampassUser) {
*/
$(document)
.on('mouseenter', '.fa-clickable', function() {
- $(this).addClass('text-info');
+ if ($(this).hasClass('warn-user')) $(this).addClass('text-danger');
+ else $(this).addClass('text-info');
})
.on('mouseleave', '.fa-clickable', function() {
- $(this).removeClass('text-info');
+ if ($(this).hasClass('warn-user')) $(this).removeClass('text-danger');
+ else $(this).removeClass('text-info');
});
$('#form-item-label').change(function() {
@@ -4005,11 +4052,13 @@ function(teampassApplication) {
icon_all_can_modify = '
';
}
+ // Open item icon
+ icon_open = '
';
+
// Prepare mini icons
if (store.get('teampassSettings') !== undefined && parseInt(store.get('teampassSettings').copy_to_clipboard_small_icons) === 1 &&
value.rights > 10
) {
- icon_open = '
';
// Login icon
if (value.login !== '') {
icon_login = '
';
@@ -4041,6 +4090,9 @@ function(teampassApplication) {
}
}
+ // Trash icon
+ trash_link = '
';
+
// Prepare Description
if (value.desc !== '') {
value.desc = '
- ' + value.desc + ' ';
@@ -4065,7 +4117,7 @@ function(teampassApplication) {
'
' +
(value.rights === 10 ?
' ' :
- pwd_error + icon_open + icon_all_can_modify + icon_login + icon_pwd + icon_link + icon_favorite) +
+ pwd_error + icon_open + icon_all_can_modify + icon_login + icon_pwd + icon_link + icon_favorite + trash_link) +
' ' +
(value.folder !== undefined ?
'
');
+ }
+
// Uncrypt the pwd
if (data.pw !== undefined) {
data.pw = atob(data.pw).utf8Decode();
@@ -4565,7 +4622,7 @@ function(teampassItem) {
// Prepare card
const itemIcon = (data.fa_icon !== "") ? ' ' : '';
$('#card-item-label, #form-item-title').html(itemIcon + data.label);
- $('#form-item-label, #form-item-suggestion-label').val(data.label);
+ $('#form-item-label, #form-item-suggestion-label').val($('').html(data.label).text());
$('#card-item-description, #form-item-suggestion-description').html(data.description);
if (data.description === '') {
$('#card-item-description').addClass('hidden');
@@ -4902,7 +4959,7 @@ function(teampassItem) {
$('#card-item-pwd-button').removeClass('hidden');
} else {
$('#card-item-pwd-button').addClass('hidden');
- $('#card-item-pwd').after('
');
+ $('#card-item-pwd').after('
');
}
// Prepare clipboard - COPY EMAIL
diff --git a/pages/profile.js.php b/pages/profile.js.php
index e6964df17..68e93d01a 100755
--- a/pages/profile.js.php
+++ b/pages/profile.js.php
@@ -500,4 +500,112 @@ function(data) {
$("#profile-saltkey-complex").val(score);
}
});
+
+ $('#profile-keys_download-date').text('');
+
+ $("#open-dialog-keys-download").on('click', function(event) {
+ event.preventDefault();
+ $('#dialog-recovery-keys-download').removeClass('hidden');
+
+ // Prepare modal
+ showModalDialogBox(
+ '#warningModal',
+ '
',
+ '',
+ '',
+ '',
+ false,
+ false,
+ false
+ );
+
+ // Actions on modal buttons
+ $(document).on('click', '#warningModalButtonClose', function() {
+ store.update(
+ 'teampassUser', {},
+ function(teampassUser) {
+ teampassUser.shown_warning_unsuccessful_login = true;
+ }
+ );
+ });
+ let RequestOnGoing = false;
+ $(document).on('click', '#warningModalButtonAction', function(event) {
+ event.preventDefault();
+
+ if (RequestOnGoing === true) {
+ return false;
+ }
+ RequestOnGoing = true;
+
+ // We have the password, start reencryption
+ $('#warningModalButtonAction')
+ .addClass('disabled')
+ .html('
');
+ $('#warningModalButtonClose').addClass('disabled');
+
+ // SHow user
+ toastr.remove();
+ toastr.info('
');
+
+ var data = {
+ 'user_id': store.get('teampassUser').user_id,
+ };
+ // Do query
+ $.post(
+ "sources/main.queries.php", {
+ 'type': "user_recovery_keys_download",
+ 'type_category': 'action_key',
+ 'data': prepareExchangedData(JSON.stringify(data), "encode", ""),
+ 'key': ''
+ },
+ function(data) {
+ data = prepareExchangedData(data, "decode", "");
+ if (debugJavascript === true) console.log(data)
+ if (data.error === true) {
+ // error
+ toastr.remove();
+ toastr.error(
+ data.message,
+ '', {
+ timeOut: 5000,
+ progressBar: true
+ }
+ );
+
+ // Enable buttons
+ $("#user-current-defuse-psk-progress").html('');
+ $('#button_do_sharekeys_reencryption, #button_close_sharekeys_reencryption').removeAttr('disabled');
+ return false;
+ } else {
+ $('#profile-keys_download-date').text(data.datetime);
+ $('#keys_not_recovered, #open_user_keys_management').addClass('hidden');
+ store.update(
+ 'teampassUser', {},
+ function(teampassUser) {
+ teampassUser.keys_recovery_time = data.datetime;
+ }
+ );
+
+ download(new Blob([atob(data.content)]), "teampass_recovery_key_"+data.login+"_"+data.timestamp+".txt", "text/text");
+
+ $("#warningModalButtonAction").addClass('hidden');
+ $('#warningModalButtonClose').removeClass('disabled');
+
+ toastr.remove();
+ RequestOnGoing = true;
+ }
+ $('#warningModalButtonAction').removeClass('disabled')
+ }
+ );
+
+ // Action
+ store.update(
+ 'teampassUser', {},
+ function(teampassUser) {
+ teampassUser.shown_warning_unsuccessful_login = true;
+ }
+ );
+ });
+
+ });
diff --git a/pages/profile.php b/pages/profile.php
index 1ffb75925..57fcd5ff5 100755
--- a/pages/profile.php
+++ b/pages/profile.php
@@ -184,10 +184,11 @@
+
+
- Timeline
+ Timeline
-
@@ -288,7 +289,7 @@
-
+
diff --git a/pages/tasks.js.php b/pages/tasks.js.php
index 58535896f..9620d2953 100755
--- a/pages/tasks.js.php
+++ b/pages/tasks.js.php
@@ -476,31 +476,97 @@ function(data) {
$('#task-define-modal-parameter-hourly, #task-define-modal-parameter-monthly').addClass('hidden');
}
});
+
+ $(document).on('click', '.task-perform', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ let taskButton = $(this);
+
+ // Prepare modal
+ showModalDialogBox(
+ '#warningModal',
+ ' ',
+ ': ' + $('#'+$(this).data('task')+'_text').text() + ' ',
+ '',
+ '',
+ false,
+ false,
+ false
+ );
- $(document).on('click', '.task-perform', function() {
- requestRunning = true;
- let launchedTask = $(this).data('task'),
- launchedButton = $(this);
+ // Actions on modal buttons
+ $(document).on('click', '#warningModalButtonAction', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ let launchedTask = $(taskButton).data('task'),
+ launchedButton = $(taskButton);
- // Inform user
- $(' ').insertAfter($(this));
- launchedButton.prop('disabled', true);
+ // Inform user
+ $(' ').insertAfter($(this));
+ launchedButton.prop('disabled', true);
- toastr.remove();
- toastr.success(
- '',
- '', {
- timeOut: 2000,
- progressBar: true
- }
- );
-
- // Store in DB
+ toastr.remove();
+ toastr.success(
+ '',
+ '', {
+ timeOut: 2000,
+ progressBar: true
+ }
+ );
+
+ // Store in DB
+ $.post(
+ "sources/tasks.queries.php",
+ {
+ type: "perform_task",
+ task: launchedTask,
+ key: ""
+ },
+ function(data) {
+ // Handle server answer
+ try {
+ data = prepareExchangedData(data, "decode", "");
+ } catch (e) {
+ // error
+ toastr.remove();
+ toastr.error(
+ '' . langHdl('server_returned_data') . ': '; ?>' + data.error,
+ '', {
+ closeButton: true,
+ positionClass: 'toastr-top-right'
+ }
+ );
+ return false;
+ }
+ console.log(data);
+ if (data.error === false) {
+ toastr.remove();
+ toastr.success(
+ '',
+ '', {
+ timeOut: 2000,
+ progressBar: true
+ }
+ );
+ }
+ $('#'+launchedTask+'_badge').text(data.datetime);
+ $('#'+launchedTask+'_spinner').remove();
+ launchedButton.prop('disabled', false);
+ requestRunning = false;
+ $('#warningModal').modal('hide');
+ }
+ );
+ });
+ });
+
+ // get last tasks execution
+ function refreshTasksTime()
+ {
+ $('#go_refresh').removeClass('hidden');
$.post(
"sources/tasks.queries.php",
{
- type: "perform_task",
- task: launchedTask,
+ type: "load_last_tasks_execution",
key: ""
},
function(data) {
@@ -520,21 +586,20 @@ function(data) {
return false;
}
- if (data.error === false) {
- toastr.remove();
- toastr.success(
- '',
- '', {
- timeOut: 2000,
- progressBar: true
- }
- );
+ let tasks = JSON.parse(data.task);
+ for (let i = 0; i < tasks.length; i++) {
+ $('#'+tasks[i].task+'_badge').text(tasks[i].datetime);
+
}
- $('#'+launchedTask+'_spinner').remove();
- launchedButton.prop('disabled', false);
- requestRunning = false;
+ $('#go_refresh').addClass('hidden');
}
);
+ }
+
+ // On page load
+ $(function() {
+ refreshTasksTime();
+ setInterval(refreshTasksTime, 10000);
});
//]]>
diff --git a/pages/tasks.php b/pages/tasks.php
index 922bff718..8da943dca 100755
--- a/pages/tasks.php
+++ b/pages/tasks.php
@@ -133,11 +133,12 @@
}?>
-
+
+
'>
@@ -150,6 +151,7 @@
+
'>
@@ -162,6 +164,7 @@
+
'>
@@ -174,6 +177,7 @@
+
'>
@@ -191,7 +195,8 @@
-
+
+
diff --git a/scripts/background_tasks___items_handler.php b/scripts/background_tasks___items_handler.php
index 717f51b29..a01bd8d60 100644
--- a/scripts/background_tasks___items_handler.php
+++ b/scripts/background_tasks___items_handler.php
@@ -116,9 +116,18 @@
doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
// launch a new iterative process
-$process = new Symfony\Component\Process\Process([$phpBinaryPath, __FILE__]);
-$process->start();
-$process->wait();
+$process_to_perform = DB::queryfirstrow(
+ 'SELECT *
+ FROM ' . prefixTable('processes') . '
+ WHERE is_in_progress = %i AND process_type IN ("item_copy", "new_item", "update_item")
+ ORDER BY increment_id ASC',
+ 1
+);
+if (DB::count() > 0) {
+ $process = new Symfony\Component\Process\Process([$phpBinaryPath, __FILE__]);
+ $process->start();
+ $process->wait();
+}
/**
* Handle the task
diff --git a/scripts/background_tasks___user_keys_creation.php b/scripts/background_tasks___user_keys_creation.php
index 4ff5f6770..ca594cc3d 100755
--- a/scripts/background_tasks___user_keys_creation.php
+++ b/scripts/background_tasks___user_keys_creation.php
@@ -122,9 +122,19 @@
doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
// launch a new iterative process
-$process = new Symfony\Component\Process\Process([$phpBinaryPath, __FILE__]);
-$process->start();
-$process->wait();
+$process_to_perform = DB::queryfirstrow(
+ 'SELECT *
+ FROM ' . prefixTable('processes') . '
+ WHERE is_in_progress = %i AND process_type = %s
+ ORDER BY increment_id ASC',
+ 1,
+ 'create_user_keys'
+);
+if (DB::count() > 0) {
+ $process = new Symfony\Component\Process\Process([$phpBinaryPath, __FILE__]);
+ $process->start();
+ $process->wait();
+}
@@ -452,17 +462,20 @@ function cronContinueReEncryptingUserSharekeysStep20(
array $SETTINGS,
array $extra_arguments
): array
-{
+{
// get user private key
$ownerInfo = getOwnerInfo($extra_arguments['owner_id'], $extra_arguments['creator_pwd'], $SETTINGS);
+ $userInfo = getOwnerInfo($extra_arguments['new_user_id'], $extra_arguments['new_user_pwd'], $SETTINGS);
// Loop on items
$rows = DB::query(
'SELECT id, pw, perso
FROM ' . prefixTable('items') . '
+ '.(isset($extra_arguments['only_personal_items']) === true && $extra_arguments['only_personal_items'] === 1 ? 'WHERE perso = 1' : '').'
ORDER BY id ASC
LIMIT ' . $post_start . ', ' . $post_length
);
+ // WHERE perso = 0
foreach ($rows as $record) {
// Get itemKey from current user
$currentUserKey = DB::queryFirstRow(
@@ -470,7 +483,8 @@ function cronContinueReEncryptingUserSharekeysStep20(
FROM ' . prefixTable('sharekeys_items') . '
WHERE object_id = %i AND user_id = %i',
$record['id'],
- $extra_arguments['owner_id']
+ //$extra_arguments['owner_id']
+ (int) $record['perso'] === 0 ? $extra_arguments['owner_id'] : $extra_arguments['new_user_id']
);
// do we have any input? (#3481)
@@ -479,13 +493,39 @@ function cronContinueReEncryptingUserSharekeysStep20(
}
// Decrypt itemkey with admin key
- $itemKey = decryptUserObjectKey($currentUserKey['share_key'], $ownerInfo['private_key']);
+ $itemKey = decryptUserObjectKey(
+ $currentUserKey['share_key'],
+ //$ownerInfo['private_key']
+ (int) $record['perso'] === 0 ? $ownerInfo['private_key'] : $userInfo['private_key']
+ );
+ // Prevent to change key if its key is empty
+ if (empty($itemKey) === true) {
+ continue;
+ }
+
// Encrypt Item key
$share_key_for_item = encryptUserObjectKey($itemKey, $user_public_key);
- // Save the key in DB
- if ($post_self_change === false && ((int) $record['perso'] === 0 || ((int) $record['perso'] === 1 && (int) $post_user_id !== (int) $extra_arguments['owner_id']))) {
+ $currentUserKey = DB::queryFirstRow(
+ 'SELECT increment_id
+ FROM ' . prefixTable('sharekeys_items') . '
+ WHERE object_id = %i AND user_id = %i',
+ $record['id'],
+ $post_user_id
+ );
+
+ if (DB::count() > 0) {
+ // NOw update
+ DB::update(
+ prefixTable('sharekeys_items'),
+ array(
+ 'share_key' => $share_key_for_item,
+ ),
+ 'increment_id = %i',
+ $currentUserKey['increment_id']
+ );
+ } else {
DB::insert(
prefixTable('sharekeys_items'),
array(
@@ -494,38 +534,6 @@ function cronContinueReEncryptingUserSharekeysStep20(
'share_key' => $share_key_for_item,
)
);
- } else {
- // Get itemIncrement from selected user
- if ((int) $post_user_id !== (int) $extra_arguments['owner_id']) {
- $currentUserKey = DB::queryFirstRow(
- 'SELECT increment_id
- FROM ' . prefixTable('sharekeys_items') . '
- WHERE object_id = %i AND user_id = %i',
- $record['id'],
- $post_user_id
- );
-
- if (DB::count() > 0) {
- // NOw update
- DB::update(
- prefixTable('sharekeys_items'),
- array(
- 'share_key' => $share_key_for_item,
- ),
- 'increment_id = %i',
- $currentUserKey['increment_id']
- );
- } else {
- DB::insert(
- prefixTable('sharekeys_items'),
- array(
- 'object_id' => (int) $record['id'],
- 'user_id' => (int) $post_user_id,
- 'share_key' => $share_key_for_item,
- )
- );
- }
- }
}
}
@@ -670,6 +678,7 @@ function cronContinueReEncryptingUserSharekeysStep40(
{
// get user private key
$ownerInfo = getOwnerInfo($extra_arguments['owner_id'], $extra_arguments['creator_pwd'], $SETTINGS);
+ $userInfo = getOwnerInfo($extra_arguments['new_user_id'], $extra_arguments['new_user_pwd'], $SETTINGS);
// Loop on fields
$rows = DB::query(
@@ -869,22 +878,24 @@ function cronContinueReEncryptingUserSharekeysStep60(
{
// get user private key
$ownerInfo = getOwnerInfo($extra_arguments['owner_id'], $extra_arguments['creator_pwd'], $SETTINGS);
+ $userInfo = getOwnerInfo($extra_arguments['new_user_id'], $extra_arguments['new_user_pwd'], $SETTINGS);
// Loop on files
$rows = DB::query(
- 'SELECT id
- FROM ' . prefixTable('files') . '
- WHERE status = "' . TP_ENCRYPTION_NAME . '"
+ 'SELECT f.id AS id, i.perso AS perso
+ FROM ' . prefixTable('files') . ' AS f
+ INNER JOIN ' . prefixTable('items') . ' AS i ON i.id = f.id_item
+ WHERE f.status = "' . TP_ENCRYPTION_NAME . '"
LIMIT ' . $post_start . ', ' . $post_length
); //aes_encryption
foreach ($rows as $record) {
// Get itemKey from current user
$currentUserKey = DB::queryFirstRow(
- 'SELECT share_key
+ 'SELECT share_key, increment_id
FROM ' . prefixTable('sharekeys_files') . '
WHERE object_id = %i AND user_id = %i',
$record['id'],
- $extra_arguments['owner_id']
+ (int) $record['perso'] === 0 ? $extra_arguments['owner_id'] : $extra_arguments['new_user_id']
);
// do we have any input? (#3481)
@@ -892,14 +903,50 @@ function cronContinueReEncryptingUserSharekeysStep60(
continue;
}
- // Decrypt itemkey with admin key
- $itemKey = decryptUserObjectKey($currentUserKey['share_key'], $ownerInfo['private_key']);
+ // Decrypt itemkey with user key
+ $itemKey = decryptUserObjectKey(
+ $currentUserKey['share_key'],
+ //$ownerInfo['private_key']
+ (int) $record['perso'] === 0 ? $ownerInfo['private_key'] : $userInfo['private_key']
+ );
+
+ // Prevent to change key if its key is empty
+ if (empty($itemKey) === true) {
+ continue;
+ }
// Encrypt Item key
$share_key_for_item = encryptUserObjectKey($itemKey, $user_public_key);
+ $currentUserKey = DB::queryFirstRow(
+ 'SELECT increment_id
+ FROM ' . prefixTable('sharekeys_files') . '
+ WHERE object_id = %i AND user_id = %i',
+ $record['id'],
+ $post_user_id
+ );
// Save the key in DB
- if ($post_self_change === false) {
+ if (DB::count() > 0) {
+ // NOw update
+ DB::update(
+ prefixTable('sharekeys_files'),
+ array(
+ 'share_key' => $share_key_for_item,
+ ),
+ 'increment_id = %i',
+ $currentUserKey['increment_id']
+ );
+ } else {
+ DB::insert(
+ prefixTable('sharekeys_files'),
+ array(
+ 'object_id' => (int) $record['id'],
+ 'user_id' => (int) $post_user_id,
+ 'share_key' => $share_key_for_item,
+ )
+ );
+ }
+ /*if ($post_self_change === false) {
DB::insert(
prefixTable('sharekeys_files'),
array(
@@ -913,7 +960,7 @@ function cronContinueReEncryptingUserSharekeysStep60(
if ((int) $post_user_id !== (int) $extra_arguments['owner_id']) {
$currentUserKey = DB::queryFirstRow(
'SELECT increment_id
- FROM ' . prefixTable('sharekeys_items') . '
+ FROM ' . prefixTable('sharekeys_files') . '
WHERE object_id = %i AND user_id = %i',
$record['id'],
$post_user_id
@@ -929,7 +976,7 @@ function cronContinueReEncryptingUserSharekeysStep60(
'increment_id = %i',
$currentUserKey['increment_id']
);
- }
+ }*/
}
// SHould we change step? Finished ?
diff --git a/scripts/task_maintenance_clean_orphan_objects.php b/scripts/task_maintenance_clean_orphan_objects.php
index 72b73d56b..1b5594037 100644
--- a/scripts/task_maintenance_clean_orphan_objects.php
+++ b/scripts/task_maintenance_clean_orphan_objects.php
@@ -56,13 +56,13 @@
DB::$connect_options = DB_CONNECT_OPTIONS;
// log start
-$logID = doLog('start', 'do_maintenance - clean-orphan-objects', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0));
+$logID = doLog('start', 'do_maintenance - clean-orphan-objects', 1);
// Perform maintenance tasks
cleanOrphanObjects();
// log end
-doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
+doLog('end', '', 1, $logID);
/**
* Delete all orphan objects from DB
diff --git a/scripts/task_maintenance_purge_old_files.php b/scripts/task_maintenance_purge_old_files.php
index d493cb640..ce0459749 100644
--- a/scripts/task_maintenance_purge_old_files.php
+++ b/scripts/task_maintenance_purge_old_files.php
@@ -56,13 +56,13 @@
DB::$connect_options = DB_CONNECT_OPTIONS;
// log start
-$logID = doLog('start', 'do_maintenance - purge-old-files', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0));
+$logID = doLog('start', 'do_maintenance - purge-old-files', 1);
// Perform maintenance tasks
purgeTemporaryFiles();
// log end
-doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
+doLog('end', '', 1, $logID);
/**
* Purge old files in FILES and UPLOAD folders.
*
diff --git a/scripts/task_maintenance_rebuild_config_file.php b/scripts/task_maintenance_rebuild_config_file.php
index 490eff043..76e48888d 100644
--- a/scripts/task_maintenance_rebuild_config_file.php
+++ b/scripts/task_maintenance_rebuild_config_file.php
@@ -55,13 +55,13 @@
DB::$connect_options = DB_CONNECT_OPTIONS;
// log start
-$logID = doLog('start', 'do_maintenance - rebuild-config-file', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0));
+$logID = doLog('start', 'do_maintenance - rebuild-config-file', 1);
// Perform maintenance tasks
rebuildConfigFile();
// log end
-doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
+doLog('end', '', 1, $logID);
/**
diff --git a/scripts/task_maintenance_reload_cache_table.php b/scripts/task_maintenance_reload_cache_table.php
index 8833bf55b..daaaf9fdb 100644
--- a/scripts/task_maintenance_reload_cache_table.php
+++ b/scripts/task_maintenance_reload_cache_table.php
@@ -56,13 +56,13 @@
DB::$connect_options = DB_CONNECT_OPTIONS;
// log start
-$logID = doLog('start', 'do_maintenance - reload-cache-table', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0));
+$logID = doLog('start', 'do_maintenance - reload-cache-table', 1);
// Perform maintenance tasks
reloadCacheTable();
// log end
-doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
+doLog('end', '', 1, $logID);
/**
* Relead cache table
diff --git a/scripts/task_maintenance_users_personal_folder.php b/scripts/task_maintenance_users_personal_folder.php
index d8af45ca3..e7d961615 100644
--- a/scripts/task_maintenance_users_personal_folder.php
+++ b/scripts/task_maintenance_users_personal_folder.php
@@ -56,13 +56,13 @@
DB::$connect_options = DB_CONNECT_OPTIONS;
// log start
-$logID = doLog('start', 'do_maintenance - users-personal-folder', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0));
+$logID = doLog('start', 'do_maintenance - users-personal-folder', 1);
// Perform maintenance tasks
createUserPersonalFolder();
// log end
-doLog('end', '', (isset($SETTINGS['enable_tasks_log']) === true ? (int) $SETTINGS['enable_tasks_log'] : 0), $logID);
+doLog('end', '', 1, $logID);
/**
* Permits to create the personal folder for each user.
@@ -150,23 +150,5 @@ function createUserPersonalFolder(): void
// Ensure only the user items have a sharekey
purgeUnnecessaryKeys(false, $user['id']);
- /*
- $personalItems = DB::queryFirstColumn(
- 'SELECT id
- FROM ' . prefixTable('items') . ' AS i
- INNER JOIN ' . prefixTable('log_items') . ' AS li ON li.id_item = i.id
- WHERE i.perso = 1 AND li.action = "at_creation" AND li.id_user = %i',
- $user['id']
- );
- if (count($personalItems) > 0) {
- print_r($personalItems);
- DB::delete(
- prefixTable('sharekeys_items'),
- 'object_id IN %li AND user_id != %i',
- $personalItems,
- $user['id']
- );
- }
- */
}
}
diff --git a/sources/identify.php b/sources/identify.php
index 608c0ef72..e8e49b324 100755
--- a/sources/identify.php
+++ b/sources/identify.php
@@ -492,6 +492,7 @@ function identifyUser(string $sentData, array $SETTINGS): bool
$superGlobal->put('user_language', $userInfo['user_language'], 'SESSION', 'user');
$superGlobal->put('user_timezone', $userInfo['usertimezone'], 'SESSION', 'user');
$superGlobal->put('session_duration', $dataReceived['duree_session'] * 60, 'SESSION', 'user');
+ $superGlobal->put('keys_recovery_time', $userInfo['keys_recovery_time'], 'SESSION', 'user');
// User signature keys
$returnKeys = prepareUserEncryptionKeys($userInfo, $passwordClear);
diff --git a/sources/items.queries.php b/sources/items.queries.php
index 1b6ef17c1..601596c6f 100755
--- a/sources/items.queries.php
+++ b/sources/items.queries.php
@@ -462,7 +462,7 @@
'files' => [],
);
- // Create sharekeys for users
+ // Create sharekeys for the user itself
storeUsersShareKey(
prefixTable('sharekeys_items'),
(int) $post_folder_is_personal,
@@ -470,7 +470,8 @@
(int) $newID,
$objectKey['pwd'],
$SETTINGS,
- true
+ true, // only for the item creator
+ false, // no delete all
);
// update fields
@@ -523,7 +524,8 @@
(int) $newObjectId,
$cryptedStuff['objectKey'],
$SETTINGS,
- true
+ true, // only for the item creator
+ false, // no delete all
);
} else {
@@ -726,7 +728,7 @@
// Create new task for the new item
// If it is not a personnal one
- if (isset($post_folder_is_personal) === false || (int) $post_folder_is_personal === 0) {
+ if ((int) $post_folder_is_personal === 0) {
storeTask(
'new_item',
$_SESSION['user_id'],
@@ -1134,7 +1136,6 @@
//-----
// NEW ENCRYPTION
$cryptedStuff = doDataEncryption($post_password);
-
$encrypted_password = $cryptedStuff['encrypted'];
// Create sharekeys for users
@@ -1341,13 +1342,17 @@
);
// Decrypt the current value
- $oldVal = base64_decode(doDataDecryption(
- $dataTmpCat['data'],
- decryptUserObjectKey(
- $userKey['share_key'],
- $_SESSION['user']['private_key']
- )
- ));
+ if (DB::count() > 0) {
+ $oldVal = base64_decode(doDataDecryption(
+ $dataTmpCat['data'],
+ decryptUserObjectKey(
+ $userKey['share_key'],
+ $_SESSION['user']['private_key']
+ )
+ ));
+ } else {
+ $oldVal = '';
+ }
} else {
$oldVal = $dataTmpCat['data'];
}
@@ -2542,8 +2547,13 @@
$dataItem['pw'],
$decryptedObject
);
+ $arrData['pwd_encryption_error'] = false;
+ $arrData['pwd_encryption_error_message'] = '';
} else {
- echo (string) prepareExchangedData(
+ $pw = '';
+ $arrData['pwd_encryption_error'] = 'inconsistent_password';
+ $arrData['pwd_encryption_error_message'] = langHdl('error_new_ldap_password_detected');
+ /*echo (string) prepareExchangedData(
$SETTINGS['cpassman_dir'],
array(
'error' => true,
@@ -2552,8 +2562,7 @@
'error_type' => 'inconsistent_password',
),
'encode'
- );
- break;
+ );*/
}
}
@@ -3274,11 +3283,27 @@
$inputData['data'],
'decode'
);
-
+
// Prepare POST variables
- $inputData['folderId'] = (int) filter_var($dataReceived['folder_id'], FILTER_SANITIZE_NUMBER_INT);
- $inputData['itemId'] = (int) filter_var($dataReceived['item_id'], FILTER_SANITIZE_NUMBER_INT);
- $post_access_level = (int) filter_var($dataReceived['access_level'], FILTER_SANITIZE_NUMBER_INT);
+ $data = [
+ 'itemId' => isset($dataReceived['item_id']) === true ? $dataReceived['item_id'] : '',
+ 'folderId' => isset($dataReceived['folder_id']) === true ? $dataReceived['folder_id'] : '',
+ 'accessLevel' => isset($dataReceived['access_level']) === true ? $dataReceived['access_level'] : '',
+ 'itemKey' => isset($dataReceived['item_key']) === true ? $dataReceived['item_key'] : '',
+ ];
+
+ $filters = [
+ 'itemId' => 'cast:integer',
+ 'folderId' => 'cast:integer',
+ 'accessLevel' => 'cast:integer',
+ 'itemKey' => 'trim|escape',
+ ];
+
+ $inputData = dataSanitizer(
+ $data,
+ $filters,
+ $SETTINGS['cpassman_dir']
+ );
// Check that user can access this item
$granted = accessToItemIsGranted($inputData['itemId'], $SETTINGS);
@@ -3296,11 +3321,16 @@
// Load item data
$data = DB::queryFirstRow(
- 'SELECT id_tree
+ 'SELECT id_tree, id, label
FROM ' . prefixTable('items') . '
- WHERE id = %i',
- $inputData['itemId']
+ WHERE id = %i OR item_key = %s',
+ $inputData['itemId'],
+ $inputData['itemKey']
);
+ if (empty($inputData['itemId']) === true) {
+ $inputData['itemId'] = $data['id'];
+ }
+ $inputData['label'] = $data['label'];
// delete item consists in disabling it
DB::update(
@@ -3309,8 +3339,9 @@
'inactif' => '1',
'deleted_at' => time(),
),
- 'id = %i',
- $inputData['itemId']
+ 'id = %i OR item_key = %s',
+ $inputData['itemId'],
+ $inputData['itemKey']
);
// log
@@ -3619,7 +3650,7 @@
$post_nb_items_to_display_once = filter_var($dataReceived['nb_items_to_display_once'], FILTER_SANITIZE_NUMBER_INT);
$arr_arbo = [];
- $folderIsPf = false;
+ $folderIsPf = in_array($inputData['id'], $_SESSION['personal_folders']) === true ? true : false;
$showError = 0;
$itemsIDList = $rights = $returnedData = $uniqueLoadData = $html_json = array();
// Build query limits
@@ -3636,7 +3667,6 @@
foreach ($arbo as $elem) {
if ($elem->title === $_SESSION['user_id'] && (int) $elem->nlevel === 1) {
$elem->title = $_SESSION['login'];
- $folderIsPf = true;
}
// Store path elements
array_push(
@@ -4275,6 +4305,15 @@
$_SESSION['user']['private_key']
)
);
+
+ $log = 'Used user ID: '.$_SESSION['user_id']."\n";
+ $log .= 'Used user Private key: '.$_SESSION['user']['private_key']."\n";
+ $log .= '$currentUserKey: '.$dataItem['share_key']."\n";
+ $log .= 'itemKey: '.decryptUserObjectKey(
+ $dataItem['share_key'],
+ $_SESSION['user']['private_key']
+ )."\n\n";
+ file_put_contents('/var/www/html/tplog.log', $log, FILE_APPEND | LOCK_EX);
}
$returnValues = array(
diff --git a/sources/main.functions.php b/sources/main.functions.php
index f179a2524..71b0a1b42 100755
--- a/sources/main.functions.php
+++ b/sources/main.functions.php
@@ -3016,11 +3016,10 @@ function storeUsersShareKey(
}
if (
- (int) $post_folder_is_personal === 1
- && in_array($post_folder_id, $superGlobal->get('personal_folders', 'SESSION')) === true
+ //((int) $post_folder_is_personal === 1 && in_array($post_folder_id, $superGlobal->get('personal_folders', 'SESSION')) === true) ||
+ $onlyForUser === true || (int) $post_folder_is_personal === 1
) {
- // If this is a personal object
- // Only create the sharekey for user
+ // Only create the sharekey for a user
$user = DB::queryFirstRow(
'SELECT public_key
FROM ' . prefixTable('users') . '
@@ -3056,7 +3055,6 @@ function storeUsersShareKey(
}
}
} else {
- // This is a public object
// Create sharekey for each user
//DB::debugmode(true);
$users = DB::query(
@@ -3238,33 +3236,44 @@ function deleteUserObjetsKeys(int $userId, array $SETTINGS = []): bool
DB::$ssl = DB_SSL;
DB::$connect_options = DB_CONNECT_OPTIONS;
// Remove all item sharekeys items
+ // expect if personal item
DB::delete(
prefixTable('sharekeys_items'),
- 'user_id = %i',
+ 'user_id = %i AND object_id NOT IN (SELECT i.id FROM ' . prefixTable('items') . ' AS i WHERE i.perso = 1)',
$userId
);
// Remove all item sharekeys files
DB::delete(
prefixTable('sharekeys_files'),
- 'user_id = %i',
+ 'user_id = %i AND object_id NOT IN (
+ SELECT f.id
+ FROM ' . prefixTable('items') . ' AS i
+ INNER JOIN ' . prefixTable('files') . ' AS f ON f.id_item = i.id
+ WHERE i.perso = 1
+ )',
$userId
);
// Remove all item sharekeys fields
DB::delete(
prefixTable('sharekeys_fields'),
- 'user_id = %i',
+ 'user_id = %i AND object_id NOT IN (
+ SELECT c.id
+ FROM ' . prefixTable('items') . ' AS i
+ INNER JOIN ' . prefixTable('categories_items') . ' AS c ON c.item_id = i.id
+ WHERE i.perso = 1
+ )',
$userId
);
// Remove all item sharekeys logs
DB::delete(
prefixTable('sharekeys_logs'),
- 'user_id = %i',
+ 'user_id = %i AND object_id NOT IN (SELECT i.id FROM ' . prefixTable('items') . ' AS i WHERE i.perso = 1)',
$userId
);
// Remove all item sharekeys suggestions
DB::delete(
prefixTable('sharekeys_suggestions'),
- 'user_id = %i',
+ 'user_id = %i AND object_id NOT IN (SELECT i.id FROM ' . prefixTable('items') . ' AS i WHERE i.perso = 1)',
$userId
);
return false;
@@ -3993,6 +4002,9 @@ function upgradeRequired(): bool
* @param boolean $encryptWithUserPassword
* @param boolean $generate_user_new_password
* @param string $emailBody
+ * @param boolean $user_self_change
+ * @param string $recovery_public_key
+ * @param string $recovery_private_key
* @return string
*/
function handleUserKeys(
@@ -4004,7 +4016,10 @@ function handleUserKeys(
bool $sendEmailToUser = true,
bool $encryptWithUserPassword = false,
bool $generate_user_new_password = false,
- string $emailBody = ''
+ string $emailBody = '',
+ bool $user_self_change = false,
+ string $recovery_public_key = '',
+ string $recovery_private_key = '',
): string
{
@@ -4039,7 +4054,15 @@ function handleUserKeys(
}
// Generate new keys
- $userKeys = generateUserKeys($passwordClear);
+ if ($user_self_change === true && empty($recovery_public_key) === false && empty($recovery_private_key) === false){
+ $userKeys = [
+ 'public_key' => $recovery_public_key,
+ 'private_key_clear' => $recovery_private_key,
+ 'private_key' => encryptPrivateKey($passwordClear, $recovery_private_key),
+ ];
+ } else {
+ $userKeys = generateUserKeys($passwordClear);
+ }
// Save in DB
DB::update(
@@ -4078,6 +4101,8 @@ function handleUserKeys(
'send_email' => $sendEmailToUser === true ? 1 : 0,
'otp_provided_new_value' => 1,
'email_body' => empty($emailBody) === true ? '' : langHdl($emailBody),
+ 'user_self_change' => $user_self_change === true ? 1 : 0,
+ 'only_personal_items' => $only_personal_items === true ? 1 : 0,
]),
'updated_at' => '',
'finished_at' => '',
@@ -4389,6 +4414,21 @@ function getPHPBinary(): string
function purgeUnnecessaryKeys(bool $allUsers = true, int $user_id=0)
{
if ($allUsers === true) {
+ include_once __DIR__. '/../sources/SplClassLoader.php';
+ //Connect to DB
+ include_once __DIR__. '/../includes/libraries/Database/Meekrodb/db.class.php';
+ if (defined('DB_PASSWD_CLEAR') === false) {
+ define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
+ }
+ DB::$host = DB_HOST;
+ DB::$user = DB_USER;
+ DB::$password = DB_PASSWD_CLEAR;
+ DB::$dbName = DB_NAME;
+ DB::$port = DB_PORT;
+ DB::$encoding = DB_ENCODING;
+ DB::$ssl = DB_SSL;
+ DB::$connect_options = DB_CONNECT_OPTIONS;
+
$users = DB::query(
'SELECT id
FROM ' . prefixTable('users') . '
@@ -4396,10 +4436,10 @@ function purgeUnnecessaryKeys(bool $allUsers = true, int $user_id=0)
ORDER BY login ASC'
);
foreach ($users as $user) {
- purgeUnnecessaryKeysForUser($user['id']);
+ purgeUnnecessaryKeysForUser((int) $user['id']);
}
} else {
- purgeUnnecessaryKeysForUser($user_id);
+ purgeUnnecessaryKeysForUser((int) $user_id);
}
}
@@ -4415,20 +4455,121 @@ function purgeUnnecessaryKeysForUser(int $user_id=0)
return;
}
+ include_once __DIR__. '/../sources/SplClassLoader.php';
+ //Connect to DB
+ include_once __DIR__. '/../includes/libraries/Database/Meekrodb/db.class.php';
+ if (defined('DB_PASSWD_CLEAR') === false) {
+ define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
+ }
+ DB::$host = DB_HOST;
+ DB::$user = DB_USER;
+ DB::$password = DB_PASSWD_CLEAR;
+ DB::$dbName = DB_NAME;
+ DB::$port = DB_PORT;
+ DB::$encoding = DB_ENCODING;
+ DB::$ssl = DB_SSL;
+ DB::$connect_options = DB_CONNECT_OPTIONS;
+
$personalItems = DB::queryFirstColumn(
'SELECT id
FROM ' . prefixTable('items') . ' AS i
INNER JOIN ' . prefixTable('log_items') . ' AS li ON li.id_item = i.id
- WHERE i.perso = 1 AND li.action = "at_creation" AND li.id_user = %i',
+ WHERE i.perso = 1 AND li.action = "at_creation" AND li.id_user IN (%i, '.TP_USER_ID.')',
$user_id
);
if (count($personalItems) > 0) {
- print_r($personalItems);
+ // Item keys
DB::delete(
prefixTable('sharekeys_items'),
- 'object_id IN %li AND user_id != %i',
+ 'object_id IN %li AND user_id NOT IN (%i, '.TP_USER_ID.')',
$personalItems,
$user_id
);
+ // Files keys
+ DB::delete(
+ prefixTable('sharekeys_files'),
+ 'object_id IN %li AND user_id NOT IN (%i, '.TP_USER_ID.')',
+ $personalItems,
+ $user_id
+ );
+ // Fields keys
+ DB::delete(
+ prefixTable('sharekeys_fields'),
+ 'object_id IN %li AND user_id NOT IN (%i, '.TP_USER_ID.')',
+ $personalItems,
+ $user_id
+ );
+ // Logs keys
+ DB::delete(
+ prefixTable('sharekeys_logs'),
+ 'object_id IN %li AND user_id NOT IN (%i, '.TP_USER_ID.')',
+ $personalItems,
+ $user_id
+ );
+ }
+}
+
+/**
+ * Generate recovery keys file
+ *
+ * @param integer $userId
+ * @param array $SETTINGS
+ * @return string
+ */
+function handleUserRecoveryKeysDownload(int $userId, array $SETTINGS):string
+{
+ // Check if user exists
+ $userInfo = DB::queryFirstRow(
+ 'SELECT pw, public_key, private_key, login, name
+ FROM ' . prefixTable('users') . '
+ WHERE id = %i',
+ $userId
+ );
+
+ if (DB::count() > 0) {
+ $now = (int) time();
+
+ // Prepare file content
+ $export_value = file_get_contents(__DIR__."/../includes/core/teampass_ascii.txt")."\n".
+ "Generation date: ".date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], $now)."\n\n".
+ "RECOVERY KEYS - Not to be shared - To be store safely\n\n".
+ "Public Key:\n".$userInfo['public_key']."\n\n".
+ "Private Key:\n".decryptPrivateKey($_SESSION['user_pwd'], $userInfo['private_key'])."\n\n";
+
+ // Update user's keys_recovery_time
+ DB::update(
+ prefixTable('users'),
+ [
+ 'keys_recovery_time' => $now,
+ ],
+ 'id=%i',
+ $userId
+ );
+ $_SESSION['user']['keys_recovery_time'] = $now;
+
+ //Log into DB the user's disconnection
+ logEvents($SETTINGS, 'user_mngt', 'at_user_keys_download', (string) $userId, $userInfo['login']);
+
+ // Return data
+ return prepareExchangedData(
+ __DIR__.'/..',
+ array(
+ 'error' => false,
+ 'datetime' => date($SETTINGS['date_format'] . ' ' . $SETTINGS['time_format'], $now),
+ 'timestamp' => $now,
+ 'content' => base64_encode($export_value),
+ 'login' => $userInfo['login'],
+ ),
+ 'encode'
+ );
}
+
+ return prepareExchangedData(
+ __DIR__.'/..',
+ array(
+ 'error' => true,
+ 'datetime' => '',
+ ),
+ 'encode'
+ );
}
\ No newline at end of file
diff --git a/sources/main.queries.php b/sources/main.queries.php
index 0951bc125..e987ddc05 100755
--- a/sources/main.queries.php
+++ b/sources/main.queries.php
@@ -532,6 +532,18 @@ function keyHandler(string $post_type, /*php8 array|null|string */$dataReceived,
(bool) filter_var($dataReceived['encrypt_with_user_pwd'], FILTER_VALIDATE_BOOLEAN),
(bool) isset($dataReceived['generate_user_new_password']) === true ? filter_var($dataReceived['generate_user_new_password'], FILTER_VALIDATE_BOOLEAN) : false,
(string) filter_var($dataReceived['email_body'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
+ (bool) filter_var($dataReceived['user_self_change'], FILTER_VALIDATE_BOOLEAN),
+ (string) filter_var($dataReceived['recovery_public_key'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
+ (string) filter_var($dataReceived['recovery_private_key'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
+ );
+
+ /*
+ * Launch user recovery download
+ */
+ case 'user_recovery_keys_download'://action_key
+ return handleUserRecoveryKeysDownload(
+ (int) filter_var($dataReceived['user_id'], FILTER_SANITIZE_NUMBER_INT),
+ (array) $SETTINGS,
);
/*
diff --git a/sources/tasks.queries.php b/sources/tasks.queries.php
index 6ac64e775..d6dee417e 100644
--- a/sources/tasks.queries.php
+++ b/sources/tasks.queries.php
@@ -116,20 +116,128 @@
switch ($post_type) {
case 'perform_task':
- echo performTask($post_task, $SETTINGS['cpassman_dir'], $phpBinaryPath);
+ echo performTask($post_task, $SETTINGS['cpassman_dir'], $phpBinaryPath, $SETTINGS['date_format'].' '.$SETTINGS['time_format']);
break;
+
+ case 'load_last_tasks_execution':
+ echo loadLastTasksExec($SETTINGS['date_format'].' '.$SETTINGS['time_format'], $SETTINGS['cpassman_dir']);
+
+ break;
}
}
+/**
+ * Load the last tasks execution
+ *
+ * @param string $datetimeFormat
+ * @param string $dir
+ * @return void
+ */
+function loadLastTasksExec(string $datetimeFormat, string $dir)
+{
+ $lastExec = [];
+
+ // get exec from processes table
+ $rows = DB::query(
+ 'SELECT max(finished_at), process_type
+ FROM ' . prefixTable('processes') . '
+ GROUP BY process_type'
+ );
+ foreach ($rows as $row) {
+ array_push(
+ $lastExec,
+ [
+ 'task' => loadLastTasksExec_getBadge($row['process_type']),
+ 'datetime' => date($datetimeFormat, (int) $row['max(finished_at)'])
+ ]
+ );
+ }
+
+ // get exec from processes_log table
+ $rows = DB::query(
+ 'SELECT max(finished_at), job as process_type
+ FROM ' . prefixTable('processes_logs') . '
+ GROUP BY process_type'
+ );
+ foreach ($rows as $row) {
+ array_push(
+ $lastExec,
+ [
+ 'task' => loadLastTasksExec_getBadge($row['process_type']),
+ 'datetime' => date($datetimeFormat, (int) $row['max(finished_at)'])
+ ]
+ );
+ }
+
+ return prepareExchangedData(
+ $dir,
+ array(
+ 'error' => false,
+ 'task' => json_encode($lastExec),
+ ),
+ 'encode'
+ );
+}
+
+function loadLastTasksExec_getBadge(string $processLabel): string
+{
+ $existingTasks = [
+ 'do_maintenance - clean-orphan-objects' => [
+ 'db' => 'do_maintenance - clean-orphan-objects',
+ 'task' => 'clean_orphan_objects_task',
+ ],
+ 'do_maintenance - purge-old-files' => [
+ 'db' => 'do_maintenance - purge-old-files',
+ 'task' => 'purge_temporary_files_task',
+ ],
+ 'do_maintenance - rebuild-config-file' => [
+ 'db' => 'do_maintenance - rebuild-config-file',
+ 'task' => 'rebuild_config_file_task',
+ ],
+ 'do_maintenance - reload-cache-table' => [
+ 'db' => 'do_maintenance - reload-cache-table',
+ 'task' => 'reload_cache_table_task',
+ ],
+ 'do_maintenance - users-personal-folder' => [
+ 'db' => 'do_maintenance - users-personal-folder',
+ 'task' => 'users_personal_folder_task',
+ ],
+ 'send_email' => [
+ 'db' => 'send_email',
+ 'task' => 'sending_emails_job_frequency',
+ ],
+ 'do_calculation' => [
+ 'db' => 'do_calculation',
+ 'task' => 'items_statistics_job_frequency',
+ ],
+ 'item_keys' => [
+ 'db' => 'item_keys',
+ 'task' => 'items_ops_job_frequency',
+ ],
+ 'user_task' => [
+ 'db' => 'user_task',
+ 'task' => 'user_keys_job_frequency',
+ ],
+ 'sending_email' => [
+ 'db' => 'sending_email',
+ 'task' => 'sending_emails_job_frequency',
+ ],
+ ];
+
+ return isset($existingTasks[$processLabel]) === true ? $existingTasks[$processLabel]['task'] : $processLabel;
+}
+
/**
* Perform a task
*
* @param string $task
* @param string $dir
+ * @param string $phpBinaryPath
+ * @param string $datetimeFormat
* @return string
*/
-function performTask(string $task, string $dir, string $phpBinaryPath): string
+function performTask(string $task, string $dir, string $phpBinaryPath, string $datetimeFormat): string
{
switch ($task) {
case 'users_personal_folder_task':
@@ -138,31 +246,70 @@ function performTask(string $task, string $dir, string $phpBinaryPath): string
$phpBinaryPath,
__DIR__.'/../scripts/task_maintenance_users_personal_folder.php',
]);
- try {
- $process->start();
-
- while ($process->isRunning()) {
- // waiting for process to finish
- }
-
- $process->wait();
-
- $output = $process->getOutput();
- $error = false;
- } catch (ProcessFailedException $exception) {
- $error = true;
- $output = $exception->getMessage();
- }
-
- return prepareExchangedData(
- $dir,
- array(
- 'error' => $error,
- 'output' => $output,
- ),
- 'encode'
- );
+
+ break;
+
+ case 'clean_orphan_objects_task':
+
+ $process = new Symfony\Component\Process\Process([
+ $phpBinaryPath,
+ __DIR__.'/../scripts/task_maintenance_clean_orphan_objects.php',
+ ]);
+
+ break;
+
+ case 'purge_temporary_files_task':
+
+ $process = new Symfony\Component\Process\Process([
+ $phpBinaryPath,
+ __DIR__.'/../scripts/task_maintenance_purge_old_files.php',
+ ]);
+
+ break;
+
+ case 'rebuild_config_file_task':
+
+ $process = new Symfony\Component\Process\Process([
+ $phpBinaryPath,
+ __DIR__.'/../scripts/task_maintenance_rebuild_config_file.php',
+ ]);
+
+ break;
+
+ case 'reload_cache_table_task':
+
+ $process = new Symfony\Component\Process\Process([
+ $phpBinaryPath,
+ __DIR__.'/../scripts/task_maintenance_reload_cache_table.php',
+ ]);
break;
}
+
+ // execute the process
+ try {
+ $process->start();
+
+ while ($process->isRunning()) {
+ // waiting for process to finish
+ }
+
+ $process->wait();
+
+ $output = $process->getOutput();
+ $error = false;
+ } catch (ProcessFailedException $exception) {
+ $error = true;
+ $output = $exception->getMessage();
+ }
+
+ return prepareExchangedData(
+ $dir,
+ array(
+ 'error' => $error,
+ 'output' => $output,
+ 'datetime' => date($datetimeFormat, time()),
+ ),
+ 'encode'
+ );
}
\ No newline at end of file
diff --git a/sources/users.datatable.php b/sources/users.datatable.php
index 2cd69f627..3013ef823 100755
--- a/sources/users.datatable.php
+++ b/sources/users.datatable.php
@@ -229,6 +229,10 @@
((in_array($record['id'], [OTV_USER_ID, TP_USER_ID, SSH_USER_ID, API_USER_ID]) === false && (int) $record['admin'] !== 1 && ((int) $SETTINGS['duo'] === 1 || (int) $SETTINGS['google_authentication'] === 1)) ?
((int) $record['mfa_enabled'] === 1 ? '' : '
') :
''
+ ).
+ ((in_array($record['id'], [OTV_USER_ID, TP_USER_ID, SSH_USER_ID, API_USER_ID]) === false && (int) $record['admin'] !== 1 && is_null($record['keys_recovery_time']) === true) ?
+ '
' :
+ ''
);
$sOutput .= '["