unmask single field when using the toggle menu option in the popup menu, closes https://github.com/PhilippC/keepass2android/issues/71; add option for specifying the default visibility of the TOTP field, closes https://github.com/PhilippC/keepass2android/issues/1873

This commit is contained in:
Philipp Crocoll
2022-01-17 09:46:47 +01:00
parent 093ebb424e
commit 6745e0486c
5 changed files with 76 additions and 30 deletions

View File

@@ -45,6 +45,7 @@ using KeePass.DataExchange;
using KeePass.Util.Spr; using KeePass.Util.Spr;
using KeePassLib.Interfaces; using KeePassLib.Interfaces;
using KeePassLib.Serialization; using KeePassLib.Serialization;
using PluginTOTP;
using File = Java.IO.File; using File = Java.IO.File;
using Uri = Android.Net.Uri; using Uri = Android.Net.Uri;
@@ -138,7 +139,7 @@ namespace keepass2android
private PasswordFont _passwordFont = new PasswordFont(); private PasswordFont _passwordFont = new PasswordFont();
internal bool _showPassword; internal Dictionary<TextView /*the "ProtectedField" of the ProtectedTextviewGroup*/, bool> _showPassword = new Dictionary<TextView, bool>();
private int _pos; private int _pos;
private AppTask _appTask; private AppTask _appTask;
@@ -391,10 +392,12 @@ namespace keepass2android
edit.PutLong(GetString(Resource.String.UsageCount_key), usageCount + 1); edit.PutLong(GetString(Resource.String.UsageCount_key), usageCount + 1);
edit.Commit(); edit.Commit();
_showPassword = _showPasswordDefault =
!prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default)); !prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
_showTotpDefault =
!prefs.GetBoolean(GetString(Resource.String.masktotp_key), Resources.GetBoolean(Resource.Boolean.masktotp_default));
RequestWindowFeature(WindowFeatures.IndeterminateProgress); RequestWindowFeature(WindowFeatures.IndeterminateProgress);
_activityDesign.ApplyTheme(); _activityDesign.ApplyTheme();
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
@@ -567,7 +570,7 @@ namespace keepass2android
SetPasswordTypeface(valueViewVisible); SetPasswordTypeface(valueViewVisible);
if (isProtected) if (isProtected)
{ {
RegisterProtectedTextView(valueView, valueViewVisible); RegisterProtectedTextView(key, valueView, valueViewVisible);
} }
else else
@@ -700,8 +703,12 @@ namespace keepass2android
private void RegisterProtectedTextView(TextView protectedTextView, TextView visibleTextView) private void RegisterProtectedTextView(string fieldKey, TextView protectedTextView, TextView visibleTextView)
{ {
if (!_showPassword.ContainsKey(protectedTextView))
{
_showPassword[protectedTextView] = fieldKey == UpdateTotpTimerTask.TotpKey ? _showTotpDefault : _showPasswordDefault;
}
var protectedTextviewGroup = new ProtectedTextviewGroup { ProtectedField = protectedTextView, VisibleProtectedField = visibleTextView}; var protectedTextviewGroup = new ProtectedTextviewGroup { ProtectedField = protectedTextView, VisibleProtectedField = visibleTextView};
_protectedTextViews.Add(protectedTextviewGroup); _protectedTextViews.Add(protectedTextviewGroup);
SetPasswordStyle(protectedTextviewGroup); SetPasswordStyle(protectedTextviewGroup);
@@ -809,7 +816,7 @@ namespace keepass2android
PopulateStandardText(Resource.Id.entry_url, Resource.Id.entryfield_container_url, PwDefs.UrlField); PopulateStandardText(Resource.Id.entry_url, Resource.Id.entryfield_container_url, PwDefs.UrlField);
PopulateStandardText(new List<int> { Resource.Id.entry_password, Resource.Id.entry_password_visible}, Resource.Id.entryfield_container_password, PwDefs.PasswordField); PopulateStandardText(new List<int> { Resource.Id.entry_password, Resource.Id.entry_password_visible}, Resource.Id.entryfield_container_password, PwDefs.PasswordField);
RegisterProtectedTextView(FindViewById<TextView>(Resource.Id.entry_password), FindViewById<TextView>(Resource.Id.entry_password_visible)); RegisterProtectedTextView(PwDefs.PasswordField, FindViewById<TextView>(Resource.Id.entry_password), FindViewById<TextView>(Resource.Id.entry_password_visible));
RegisterTextPopup(FindViewById<RelativeLayout> (Resource.Id.groupname_container), RegisterTextPopup(FindViewById<RelativeLayout> (Resource.Id.groupname_container),
FindViewById (Resource.Id.entry_group_name), KeyGroupFullPath); FindViewById (Resource.Id.entry_group_name), KeyGroupFullPath);
@@ -885,12 +892,16 @@ namespace keepass2android
container, container,
anchor); anchor);
popupItems.Add(new CopyToClipboardPopupMenuIcon(this, _stringViews[fieldKey])); popupItems.Add(new CopyToClipboardPopupMenuIcon(this, _stringViews[fieldKey]));
if (isProtected) if (isProtected)
popupItems.Add(new ToggleVisibilityPopupMenuItem(this)); {
var valueView = container.FindViewById<TextView>(fieldKey == PwDefs.PasswordField ? Resource.Id.entry_password : Resource.Id.entry_extra);
popupItems.Add(new ToggleVisibilityPopupMenuItem(this, valueView));
}
if (fieldKey != PwDefs.UrlField //url already has a go-to-url menu if (fieldKey != PwDefs.UrlField //url already has a go-to-url menu
&& (_stringViews[fieldKey].Text.StartsWith(KeePass.AndroidAppScheme) && (_stringViews[fieldKey].Text.StartsWith(KeePass.AndroidAppScheme)
|| _stringViews[fieldKey].Text.StartsWith("http://") || _stringViews[fieldKey].Text.StartsWith("http://")
|| _stringViews[fieldKey].Text.StartsWith("https://"))) || _stringViews[fieldKey].Text.StartsWith("https://")))
{ {
popupItems.Add(new GotoUrlMenuItem(this, fieldKey)); popupItems.Add(new GotoUrlMenuItem(this, fieldKey));
} }
@@ -1070,8 +1081,10 @@ namespace keepass2android
} }
private ExportBinaryProcessManager _exportBinaryProcessManager; private ExportBinaryProcessManager _exportBinaryProcessManager;
private bool _showPasswordDefault;
private bool _showTotpDefault;
protected override void OnSaveInstanceState(Bundle outState) protected override void OnSaveInstanceState(Bundle outState)
{ {
@@ -1114,7 +1127,7 @@ namespace keepass2android
private void UpdateTogglePasswordMenu() private void UpdateTogglePasswordMenu()
{ {
IMenuItem togglePassword = _menu.FindItem(Resource.Id.menu_toggle_pass); IMenuItem togglePassword = _menu.FindItem(Resource.Id.menu_toggle_pass);
if (_showPassword) if (_showPassword.Values.All(x => x))
{ {
togglePassword.SetTitle(Resource.String.menu_hide_password); togglePassword.SetTitle(Resource.String.menu_hide_password);
} }
@@ -1134,8 +1147,9 @@ namespace keepass2android
private void SetPasswordStyle(ProtectedTextviewGroup group) private void SetPasswordStyle(ProtectedTextviewGroup group)
{ {
group.VisibleProtectedField.Visibility = _showPassword ? ViewStates.Visible : ViewStates.Gone; bool showPassword = _showPassword.GetValueOrDefault(group.ProtectedField, _showPasswordDefault);
group.ProtectedField.Visibility = !_showPassword ? ViewStates.Visible : ViewStates.Gone; group.VisibleProtectedField.Visibility = showPassword ? ViewStates.Visible : ViewStates.Gone;
group.ProtectedField.Visibility = !showPassword ? ViewStates.Visible : ViewStates.Gone;
SetPasswordTypeface(group.VisibleProtectedField); SetPasswordTypeface(group.VisibleProtectedField);
@@ -1191,15 +1205,17 @@ namespace keepass2android
task.Start(); task.Start();
break; break;
case Resource.Id.menu_toggle_pass: case Resource.Id.menu_toggle_pass:
if (_showPassword) if (_showPassword.Values.All(x => x))
{ {
item.SetTitle(Resource.String.show_password); item.SetTitle(Resource.String.show_password);
_showPassword = false; foreach (var k in _showPassword.Keys.ToList())
_showPassword[k] = false;
} }
else else
{ {
item.SetTitle(Resource.String.menu_hide_password); item.SetTitle(Resource.String.menu_hide_password);
_showPassword = true; foreach (var k in _showPassword.Keys.ToList())
_showPassword[k] = true;
} }
SetPasswordStyle(); SetPasswordStyle();
@@ -1261,9 +1277,25 @@ namespace keepass2android
pt.Run(); pt.Run();
} }
public void ToggleVisibility()
public bool GetVisibilityForProtectedView(TextView protectedView)
{
if (protectedView == null)
{
return _showPasswordDefault;
}
if (_showPassword.ContainsKey(protectedView) == false)
{
_showPassword[protectedView] = _showPasswordDefault;
}
return _showPassword[protectedView];
}
public void ToggleVisibility(TextView valueView)
{ {
_showPassword = !_showPassword;
_showPassword[valueView] = !GetVisibilityForProtectedView(valueView);
SetPasswordStyle(); SetPasswordStyle();
UpdateTogglePasswordMenu(); UpdateTogglePasswordMenu();
} }

View File

@@ -1,4 +1,5 @@
using Android.Graphics.Drawables; using Android.Graphics.Drawables;
using Android.Widget;
namespace keepass2android namespace keepass2android
{ {
@@ -8,13 +9,14 @@ namespace keepass2android
class ToggleVisibilityPopupMenuItem : IPopupMenuItem class ToggleVisibilityPopupMenuItem : IPopupMenuItem
{ {
private readonly EntryActivity _activity; private readonly EntryActivity _activity;
private readonly TextView _valueView;
public ToggleVisibilityPopupMenuItem(EntryActivity activity) public ToggleVisibilityPopupMenuItem(EntryActivity activity, TextView valueView)
{ {
_activity = activity; _activity = activity;
_valueView = valueView;
} }
public Drawable Icon public Drawable Icon
{ {
@@ -30,7 +32,7 @@ namespace keepass2android
get get
{ {
return _activity.Resources.GetString( return _activity.Resources.GetString(
_activity._showPassword ? _activity.GetVisibilityForProtectedView(_valueView) ?
Resource.String.menu_hide_password Resource.String.menu_hide_password
: Resource.String.show_password); : Resource.String.show_password);
} }
@@ -39,7 +41,7 @@ namespace keepass2android
public void HandleClick() public void HandleClick()
{ {
_activity.ToggleVisibility(); _activity.ToggleVisibility(_valueView);
} }
} }
} }

View File

@@ -66,6 +66,7 @@
<string name="master_pwd_key">change_master_pwd</string> <string name="master_pwd_key">change_master_pwd</string>
<string name="keyfile_key">keyfile</string> <string name="keyfile_key">keyfile</string>
<string name="maskpass_key">maskpass</string> <string name="maskpass_key">maskpass</string>
<string name="masktotp_key">masktotp</string>
<string name="omitbackup_key">omitbackup</string> <string name="omitbackup_key">omitbackup</string>
<string name="list_size_key">list_size</string> <string name="list_size_key">list_size</string>
<string name="design_key">design_key</string> <string name="design_key">design_key</string>
@@ -82,6 +83,7 @@
<string name="BinaryDirectory_default">/mnt/sdcard/keepass2android/binaries/</string> <string name="BinaryDirectory_default">/mnt/sdcard/keepass2android/binaries/</string>
<bool name="maskpass_default">true</bool> <bool name="maskpass_default">true</bool>
<bool name="masktotp_default">true</bool>
<bool name="keyfile_default">true</bool> <bool name="keyfile_default">true</bool>
<bool name="omitbackup_default">true</bool> <bool name="omitbackup_default">true</bool>
<bool name="TanExpiresOnUse_default">true</bool> <bool name="TanExpiresOnUse_default">true</bool>

View File

@@ -186,6 +186,10 @@
<string name="MaskedPassword">*****</string> <string name="MaskedPassword">*****</string>
<string name="maskpass_title">Mask password</string> <string name="maskpass_title">Mask password</string>
<string name="maskpass_summary">Hide passwords by default</string> <string name="maskpass_summary">Hide passwords by default</string>
<string name="masktotp_title">Mask TOTP field</string>
<string name="masktotp_summary">Hide TOTP field by default</string>
<string name="menu_about">About</string> <string name="menu_about">About</string>
<string name="menu_change_key">Change Master Key</string> <string name="menu_change_key">Change Master Key</string>
<string name="menu_copy_pass">Copy Password</string> <string name="menu_copy_pass">Copy Password</string>

View File

@@ -243,6 +243,12 @@
android:summary="@string/maskpass_summary" android:summary="@string/maskpass_summary"
android:defaultValue="@bool/maskpass_default"/> android:defaultValue="@bool/maskpass_default"/>
<CheckBoxPreference
android:key="@string/masktotp_key"
android:title="@string/masktotp_title"
android:summary="@string/masktotp_summary"
android:defaultValue="@bool/masktotp_default"/>
<CheckBoxPreference <CheckBoxPreference
android:key="@string/ShowUsernameInList_key" android:key="@string/ShowUsernameInList_key"
android:title="@string/ShowUsernameInList_title" android:title="@string/ShowUsernameInList_title"