Skip to content

Commit f4bd2db

Browse files
Merge pull request #4488 from corentin-soriano/pwd_log
Enforce password log on copy or shown action.
2 parents 9f3e75d + 747d530 commit f4bd2db

File tree

4 files changed

+216
-190
lines changed

4 files changed

+216
-190
lines changed

includes/core/load.js.php

+65
Original file line numberDiff line numberDiff line change
@@ -2082,4 +2082,69 @@ function hashUserId(userId) {
20822082
const hash = CryptoJS.SHA256(userId);
20832083
return hash.toString(CryptoJS.enc.Hex).substring(0, 16);
20842084
}
2085+
2086+
/**
2087+
* Get item password to show or copy it in clipboard.
2088+
*
2089+
* @param {string} action - Log action (ex: at_password_shown).
2090+
* @param {string} id_type - 'item_key' or 'item_id'.
2091+
* @param {number|string} id_value - The item key or id.
2092+
*
2093+
* @returns {string} - The item cleartext password if user has access.
2094+
*/
2095+
function getItemPassword(action, id_type, id_value) {
2096+
let item_password = '';
2097+
2098+
// Get password from server
2099+
$.ajax({
2100+
type: "POST",
2101+
async: false,
2102+
url: 'sources/items.queries.php',
2103+
data: 'type=get_item_password&action=' + action + '&' + id_type +
2104+
'=' + id_value + '&key=<?php echo $session->get('key'); ?>',
2105+
dataType: "",
2106+
success: function(data) {
2107+
//decrypt data
2108+
try {
2109+
data = prepareExchangedData(data, "decode", "<?php echo $session->get('key'); ?>");
2110+
} catch (e) {
2111+
// error
2112+
toastr.remove();
2113+
toastr.warning(
2114+
'<?php echo $lang->get('no_item_to_display'); ?>'
2115+
);
2116+
return false;
2117+
}
2118+
2119+
// No access
2120+
if (data.password_error !== '') {
2121+
toastr.remove();
2122+
toastr.error(
2123+
data.password_error,
2124+
'<?php echo $lang->get('caution'); ?>', {
2125+
timeOut: 5000,
2126+
progressBar: true
2127+
}
2128+
);
2129+
return false;
2130+
}
2131+
2132+
const password = simplePurifier(atob(data.password), false, false, false, false).utf8Decode();
2133+
if (password === '') {
2134+
toastr.info(
2135+
'<?php echo $lang->get('password_is_empty'); ?>',
2136+
'', {
2137+
timeOut: 2000,
2138+
positionClass: 'toast-bottom-right',
2139+
progressBar: true
2140+
}
2141+
);
2142+
}
2143+
2144+
item_password = password;
2145+
}
2146+
});
2147+
2148+
return item_password;
2149+
}
20852150
</script>

pages/items.js.php

+51-110
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,13 @@ function(teampassApplication) {
383383
$(document).on('click', '#card-item-pwd-show-button', function() {
384384
if ($(this).hasClass('pwd-shown') === false) {
385385
$(this).addClass('pwd-shown');
386-
// Prepare data to show
387-
// Is data crypted?
388-
var data = unCryptData($('#hidden-item-pwd').val(), '<?php echo $session->get('key'); ?>');
389-
if (data !== false && data !== undefined) {
390-
$('#hidden-item-pwd').val(
391-
data.password
392-
);
393-
}
386+
387+
// Get item password from server
388+
const item_pwd = getItemPassword(
389+
'at_password_shown',
390+
'item_id',
391+
store.get('teampassItem').id
392+
);
394393

395394
// Change class and show spinner
396395
$('.pwd-show-spinner')
@@ -399,16 +398,9 @@ function(teampassApplication) {
399398

400399
// display raw password
401400
$('#card-item-pwd')
402-
.text($('#hidden-item-pwd').val())
401+
.text(item_pwd)
403402
.addClass('pointer_none');
404403

405-
// log password is shown
406-
itemLog(
407-
'at_password_shown',
408-
store.get('teampassItem').id,
409-
$('#card-item-label').text()
410-
);
411-
412404
// Autohide
413405
setTimeout(() => {
414406
$(this).removeClass('pwd-shown');
@@ -2581,34 +2573,24 @@ function(ret) {
25812573
mouseStillDown = false;
25822574
showPwdContinuous();
25832575
});
2584-
var showPwdContinuous = function() {
2585-
if (mouseStillDown === true) {
2586-
// Prepare data to show
2587-
// Is data crypted?
2588-
var data = unCryptData($('#hidden-item-pwd').val(), '<?php echo $session->get('key'); ?>');
2589-
if (data !== false && data !== undefined) {
2590-
$('#hidden-item-pwd').val(
2591-
data.password
2592-
);
2593-
}
25942576

2595-
$('#card-item-pwd')
2596-
.html(
2597-
// XSS Filtering
2598-
$('<span span style="cursor:none;">').text($('#hidden-item-pwd').val()).html()
2599-
);
2577+
const showPwdContinuous = function() {
2578+
if (mouseStillDown === true
2579+
&& !$('#card-item-pwd').hasClass('pwd-shown')) {
2580+
2581+
// Get item password from server
2582+
const item_pwd = getItemPassword(
2583+
'at_password_shown',
2584+
'item_id',
2585+
store.get('teampassItem').id
2586+
);
26002587

2588+
$('#card-item-pwd').text(item_pwd);
2589+
$('#card-item-pwd').addClass('pwd-shown');
2590+
2591+
// Auto hide password
26012592
setTimeout('showPwdContinuous("card-item-pwd")', 50);
2602-
// log password is shown
2603-
if ($('#card-item-pwd').hasClass('pwd-shown') === false) {
2604-
itemLog(
2605-
'at_password_shown',
2606-
store.get('teampassItem').id,
2607-
$('#card-item-label').text()
2608-
);
2609-
$('#card-item-pwd').addClass('pwd-shown');
2610-
}
2611-
} else {
2593+
} else if(mouseStillDown !== true) {
26122594
$('#card-item-pwd')
26132595
.html('<?php echo $var['hidden_asterisk']; ?>')
26142596
.removeClass('pwd-shown');
@@ -3380,6 +3362,14 @@ function(teampassItem) {
33803362
}
33813363
);
33823364
} else {
3365+
// Get password and fill the field.
3366+
const item_pwd = getItemPassword(
3367+
'at_password_shown_edit_form',
3368+
'item_id',
3369+
store.get('teampassItem').id
3370+
);
3371+
$('#form-item-password').val(item_pwd);
3372+
33833373
$('#card-item-visibility').html(store.get('teampassItem').itemVisibility);
33843374
$('#card-item-minimum-complexity').html(store.get('teampassItem').itemMinimumComplexity);
33853375

@@ -3980,57 +3970,18 @@ function(teampassItem) {
39803970
// Send query and get password
39813971
var result = '',
39823972
error = false;
3983-
3984-
$.ajax({
3985-
type: "POST",
3986-
async: false,
3987-
url: 'sources/items.queries.php',
3988-
data: 'type=show_item_password&item_key=' + trigger.getAttribute('data-item-key') +
3989-
'&key=<?php echo $session->get('key'); ?>',
3990-
dataType: "",
3991-
success: function(data) {
3992-
//decrypt data
3993-
try {
3994-
data = prepareExchangedData(data, "decode", "<?php echo $session->get('key'); ?>");
3995-
} catch (e) {
3996-
// error
3997-
toastr.remove();
3998-
toastr.warning(
3999-
'<?php echo $lang->get('no_item_to_display'); ?>'
4000-
);
4001-
return false;
4002-
}
4003-
if (data.error === true) {
4004-
error = true;
4005-
} else {
4006-
if (data.password_error !== '') {
4007-
error = true;
4008-
} else {
4009-
result = simplePurifier(atob(data.password), false, false, false, false).utf8Decode();
4010-
}
4011-
if (result === '') {
4012-
toastr.info(
4013-
'<?php echo $lang->get('password_is_empty'); ?>',
4014-
'', {
4015-
timeOut: 2000,
4016-
positionClass: 'toast-bottom-right',
4017-
progressBar: true
4018-
}
4019-
);
4020-
}
4021-
}
4022-
}
4023-
});
4024-
return result;
3973+
3974+
// Get item password from server
3975+
const item_pwd = getItemPassword(
3976+
'at_password_copied',
3977+
'item_key',
3978+
trigger.getAttribute('data-item-key')
3979+
);
3980+
3981+
return item_pwd;
40253982
}
40263983
});
4027-
clipboardForPassword.on('success', function(e) {
4028-
itemLog(
4029-
'at_password_copied',
4030-
e.trigger.dataset.itemId,
4031-
e.trigger.dataset.itemLabel
4032-
);
4033-
3984+
clipboardForPassword.on('success', function(e) {
40343985
// Warn user about clipboard clear
40353986
if (store.get('teampassSettings').clipboard_life_duration === undefined || parseInt(store.get('teampassSettings').clipboard_life_duration) === 0) {
40363987
toastr.remove();
@@ -4834,11 +4785,6 @@ function(teampassUser) {
48344785
$('#card-item-pwd').after('<i class="fa-solid fa-bell text-orange fa-shake ml-3 delete-after-usage infotip" title="'+data.pwd_encryption_error_message+'"></i>');
48354786
}
48364787

4837-
// Uncrypt the pwd
4838-
if (data.pw !== undefined) {
4839-
data.pw = simplePurifier(atob(data.pw), false, false, false, false).utf8Decode();
4840-
}
4841-
48424788
// Update hidden variables
48434789
store.update(
48444790
'teampassItem',
@@ -4901,7 +4847,7 @@ function(teampassItem) {
49014847
$('.form-item').removeClass('hidden');
49024848
$('#folders-tree-card').addClass('hidden');
49034849
}
4904-
$('#pwd-definition-size').val(data.pw.length);
4850+
$('#pwd-definition-size').val(data.pw_length);
49054851

49064852
// Prepare card
49074853
const itemIcon = (data.fa_icon !== "") ? '<i class="'+data.fa_icon+' mr-1"></i>' : '';
@@ -4914,8 +4860,6 @@ function(teampassItem) {
49144860
$('#card-item-description').removeClass('hidden');
49154861
}
49164862
$('#card-item-pwd').html('<?php echo $var['hidden_asterisk']; ?>');
4917-
$('#hidden-item-pwd, #form-item-suggestion-password').val(data.pw);
4918-
$('#form-item-password, #form-item-password-confirmation, #form-item-server-old-password').val(data.pw);
49194863
$('#card-item-login').html(data.login);
49204864
$('#form-item-login, #form-item-suggestion-login, #form-item-server-login').val(data.login);
49214865

@@ -5179,24 +5123,25 @@ function(teampassItem) {
51795123
}
51805124

51815125
// Prepare clipboard - COPY PASSWORD
5182-
if (data.pw !== '' && store.get('teampassItem').readyToUse === true) {
5126+
if (data.pw_length > 0 && store.get('teampassItem').readyToUse === true) {
51835127
// Delete existing clipboard
51845128
if (clipboardForPasswordListItems) {
51855129
clipboardForPasswordListItems.destroy();
51865130
}
51875131
// New clipboard
51885132
clipboardForPasswordListItems = new ClipboardJS('#card-item-pwd-button', {
51895133
text: function() {
5190-
return (data.pw);
5134+
// Get item password from server
5135+
const item_pwd = getItemPassword(
5136+
'at_password_copied',
5137+
'item_id',
5138+
data.id
5139+
);
5140+
5141+
return item_pwd;
51915142
}
51925143
})
51935144
.on('success', function(e) {
5194-
itemLog(
5195-
'at_password_copied',
5196-
store.get('teampassItem').id,
5197-
$('#card-item-label').text()
5198-
);
5199-
52005145
// Warn user about clipboard clear
52015146
if (store.get('teampassSettings').clipboard_life_duration === undefined || parseInt(store.get('teampassSettings').clipboard_life_duration) === 0) {
52025147
toastr.remove();
@@ -6427,10 +6372,6 @@ function(data) {
64276372
);
64286373
});
64296374

6430-
$('#item-button-password-copy').click(function() {
6431-
$('#form-item-password-confirmation').val($('#form-item-password').val());
6432-
});
6433-
64346375
/**
64356376
* On tag badge click, launch the search query
64366377
*/

0 commit comments

Comments
 (0)