Compare commits
50 Commits
1248--totp
...
803--totp-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fb4ab84ceb | ||
![]() |
4475fac51e | ||
![]() |
13ef4ca9ff | ||
![]() |
f297ebcd40 | ||
![]() |
a5ef4ccc7a | ||
![]() |
dfd9c32251 | ||
![]() |
fdcd4321e0 | ||
![]() |
11013791ef | ||
![]() |
6958a2d189 | ||
![]() |
94ec8cf1ac | ||
![]() |
63631fa81f | ||
![]() |
107d9c6235 | ||
![]() |
8e4ee4f588 | ||
![]() |
f0a06faae1 | ||
![]() |
99db263833 | ||
![]() |
e2e42cd177 | ||
![]() |
a376c6ee0b | ||
![]() |
0326e02ddd | ||
![]() |
d75482f3bd | ||
![]() |
bca0d042a1 | ||
![]() |
29eaf5f205 | ||
![]() |
78da5e2973 | ||
![]() |
20541618f9 | ||
![]() |
e459d280f2 | ||
![]() |
705e2e4a86 | ||
![]() |
cf9b368afc | ||
![]() |
f1c6a5365c | ||
![]() |
6a61bf6364 | ||
![]() |
814571c746 | ||
![]() |
fc5587260f | ||
![]() |
674ba7bd71 | ||
![]() |
556f82f786 | ||
![]() |
58c5c5882b | ||
![]() |
a706571e66 | ||
![]() |
3997b21aec | ||
![]() |
c354612369 | ||
![]() |
4fea731c87 | ||
![]() |
e189776ba9 | ||
![]() |
31255f0c52 | ||
![]() |
059280efd0 | ||
![]() |
5edc070aa8 | ||
![]() |
95843b1134 | ||
![]() |
d2ea9b18a8 | ||
![]() |
828425ab0e | ||
![]() |
4395f422b3 | ||
![]() |
be2c28811c | ||
![]() |
fcc4d44786 | ||
![]() |
337e6324ff | ||
![]() |
49cb33a4da | ||
![]() |
c934755e1c |
@@ -91,7 +91,29 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
private static String ExtractHost(String url)
|
||||
public PwGroup SearchForUuid(Database database, string uuid)
|
||||
{
|
||||
SearchParameters sp = SearchParameters.None;
|
||||
sp.SearchInUuids = true;
|
||||
sp.SearchString = uuid;
|
||||
|
||||
if (sp.RegularExpression) // Validate regular expression
|
||||
{
|
||||
new Regex(sp.SearchString);
|
||||
}
|
||||
|
||||
string strGroupName = _app.GetResourceString(UiStringKey.search_results);
|
||||
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) { IsVirtual = true };
|
||||
|
||||
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
||||
|
||||
database.Root.SearchEntries(sp, listResults, new NullStatusLogger());
|
||||
|
||||
return pgResults;
|
||||
|
||||
}
|
||||
|
||||
private static String ExtractHost(String url)
|
||||
{
|
||||
return UrlUtil.GetHost(url.Trim());
|
||||
}
|
||||
|
@@ -72,8 +72,9 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
|
||||
private bool? _hasTotpEntries;
|
||||
|
||||
public bool ReloadRequested { get; set; }
|
||||
public bool ReloadRequested { get; set; }
|
||||
|
||||
public bool DidOpenFileChange()
|
||||
{
|
||||
@@ -104,8 +105,9 @@ namespace keepass2android
|
||||
SearchHelper = new SearchDbHelper(app);
|
||||
|
||||
_databaseFormat = databaseFormat;
|
||||
_hasTotpEntries = null;
|
||||
|
||||
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
|
||||
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -174,10 +176,17 @@ namespace keepass2android
|
||||
PwGroup group = SearchHelper.SearchForExactUrl(this, url);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
||||
}
|
||||
public PwGroup SearchForUuid(String uuid)
|
||||
{
|
||||
PwGroup group = SearchHelper.SearchForUuid(this, uuid);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
||||
PwGroup group = SearchHelper.SearchForHost(this, url, allowSubdomains);
|
||||
|
||||
return group;
|
||||
@@ -193,8 +202,21 @@ namespace keepass2android
|
||||
|
||||
trans.CommitWrite();
|
||||
}
|
||||
|
||||
}
|
||||
_hasTotpEntries = null;
|
||||
|
||||
}
|
||||
|
||||
public bool HasTotpEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hasTotpEntries == null)
|
||||
{
|
||||
_hasTotpEntries = true;
|
||||
}
|
||||
return _hasTotpEntries.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateGlobals(PwGroup currentGroup, bool checkForDuplicateUuids )
|
||||
{
|
||||
|
@@ -47,15 +47,15 @@
|
||||
<!-- Category title for text prediction -->
|
||||
<string name="prediction_category">Instellingen voor woordsuggesties</string>
|
||||
<!-- Description for text prediction -->
|
||||
<string name="prediction_summary">Automatisch voltooien tijdens typen inschakelen</string>
|
||||
<string name="prediction_summary">Automatisch aanvullen tijdens typen inschakelen</string>
|
||||
<!-- Dialog title for auto complete choices -->
|
||||
<string name="auto_complete_dialog_title">Automatisch voltooien</string>
|
||||
<string name="auto_complete_dialog_title">Automatisch aanvullen</string>
|
||||
<!-- Option to enable text prediction in landscape -->
|
||||
<string name="prediction_landscape">Tekstveld vergroten</string>
|
||||
<!-- Description for text prediction -->
|
||||
<string name="prediction_landscape_summary">Woordsuggesties verbergen in liggende weergave</string>
|
||||
<!-- Option to enable auto capitalization of sentences -->
|
||||
<string name="auto_cap">Auto-hoofdlettergebruik</string>
|
||||
<string name="auto_cap">Automatisch hoofdlettergebruik</string>
|
||||
<!-- Description for auto cap -->
|
||||
<string name="auto_cap_summary">Hoofdletter gebruiken aan het begin van een zin</string>
|
||||
<!-- Option to enable auto punctuate -->
|
||||
@@ -64,15 +64,15 @@
|
||||
<!-- Option to enable quick fixes -->
|
||||
<string name="quick_fixes">Snelle oplossingen</string>
|
||||
<!-- Description for quick fixes -->
|
||||
<string name="quick_fixes_summary">Hiermee worden veelvoorkomende typefouten gecorrigeerd</string>
|
||||
<string name="quick_fixes_summary">Corrigeert veelgemaakte typefouten</string>
|
||||
<!-- Option to enable showing suggestions -->
|
||||
<string name="show_suggestions">Suggesties weergeven</string>
|
||||
<!-- Description for show suggestions -->
|
||||
<string name="show_suggestions_summary">Voorgestelde woorden weergeven tijdens typen</string>
|
||||
<string name="show_suggestions_summary">Woordsuggesties tijdens het typen tonen</string>
|
||||
<!-- Option to enable auto completion -->
|
||||
<string name="auto_complete">Auto-aanvullen</string>
|
||||
<!-- Description for auto completion -->
|
||||
<string name="auto_complete_summary">Gemarkeerd woord automatisch invoegen met spatiebalk en interpunctie</string>
|
||||
<string name="auto_complete_summary">Spatiebalk en interpunctie voegen automatisch gemarkeerd woord in</string>
|
||||
<!-- Option to show/hide the settings key -->
|
||||
<string name="prefs_settings_key">Instellingscode weergeven</string>
|
||||
<!-- Array of the settings key mode values -->
|
||||
|
@@ -56,15 +56,15 @@
|
||||
<string name="afc_title_sort_by">Sorteer op…</string>
|
||||
<string name="afc_yesterday">Gisteren</string>
|
||||
<plurals name="afc_title_choose_directories">
|
||||
<item quantity="one">Kies map…</item>
|
||||
<item quantity="other">Kies mappen…</item>
|
||||
<item quantity="one">Kies map…</item>
|
||||
<item quantity="other">Kies mappen…</item>
|
||||
</plurals>
|
||||
<plurals name="afc_title_choose_files">
|
||||
<item quantity="one">Kies bestand…</item>
|
||||
<item quantity="other">Kies bestanden…</item>
|
||||
<item quantity="one">Kies bestand…</item>
|
||||
<item quantity="other">Kies bestanden…</item>
|
||||
</plurals>
|
||||
<plurals name="afc_title_choose_files_directories">
|
||||
<item quantity="one">Kies bestand/ map…</item>
|
||||
<item quantity="other">Kies bestanden/ mappen…</item>
|
||||
<item quantity="one">Kies bestand/ map…</item>
|
||||
<item quantity="other">Kies bestanden/ mappen…</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
@@ -32,6 +32,7 @@ using Android.Text.Method;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Android.Content.PM;
|
||||
using Android.Webkit;
|
||||
using Android.Graphics;
|
||||
@@ -49,7 +50,9 @@ using PluginTOTP;
|
||||
using File = Java.IO.File;
|
||||
using Uri = Android.Net.Uri;
|
||||
using keepass2android.fileselect;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
using Boolean = Java.Lang.Boolean;
|
||||
using Android.Util;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -286,6 +289,8 @@ namespace keepass2android
|
||||
extraGroup.AddView(view.View);
|
||||
}
|
||||
|
||||
SetPasswordStyle();
|
||||
|
||||
//update the Entry output in the App database and notify the CopyToClipboard service
|
||||
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
@@ -488,10 +493,11 @@ namespace keepass2android
|
||||
_pluginFieldReceiver = new PluginFieldReceiver(this);
|
||||
RegisterReceiver(_pluginFieldReceiver, new IntentFilter(Strings.ActionSetEntryField));
|
||||
|
||||
new Thread(NotifyPluginsOnOpen).Start();
|
||||
var notifyPluginsOnOpenThread = new Thread(NotifyPluginsOnOpen);
|
||||
notifyPluginsOnOpenThread.Start();
|
||||
|
||||
//the rest of the things to do depends on the current app task:
|
||||
AppTask.CompleteOnCreateEntryActivity(this);
|
||||
AppTask.CompleteOnCreateEntryActivity(this, notifyPluginsOnOpenThread);
|
||||
}
|
||||
|
||||
private void RemoveFromHistory()
|
||||
@@ -664,7 +670,7 @@ namespace keepass2android
|
||||
EditModeBase editMode = new DefaultEdit();
|
||||
if (KpEntryTemplatedEdit.IsTemplated(App.Kp2a.CurrentDb, this.Entry))
|
||||
editMode = new KpEntryTemplatedEdit(App.Kp2a.CurrentDb, this.Entry);
|
||||
foreach (var key in editMode.SortExtraFieldKeys(Entry.Strings.GetKeys().Where(key=> !PwDefs.IsStandardField(key))))
|
||||
foreach (var key in editMode.SortExtraFieldKeys(Entry.Strings.GetKeys().Where(key=> !PwDefs.IsStandardField(key) && key != Kp2aTotp.TotpKey)))
|
||||
{
|
||||
if (editMode.IsVisible(key))
|
||||
{
|
||||
@@ -715,7 +721,7 @@ namespace keepass2android
|
||||
var stringView = new ExtraStringView(layout, valueView, valueViewVisible, keyView);
|
||||
|
||||
_stringViews.Add(key, stringView);
|
||||
RegisterTextPopup(valueViewContainer, valueViewContainer.FindViewById(Resource.Id.extra_vdots), key, isProtected);
|
||||
RegisterTextPopup(valueViewContainer, valueViewContainer.FindViewById(Resource.Id.extra_vdots), key, isProtected, layout);
|
||||
|
||||
return stringView;
|
||||
|
||||
@@ -725,6 +731,7 @@ namespace keepass2android
|
||||
|
||||
private List<IPopupMenuItem> RegisterPopup(string popupKey, View clickView, View anchorView)
|
||||
{
|
||||
|
||||
clickView.Click += (sender, args) =>
|
||||
{
|
||||
ShowPopup(anchorView, popupKey);
|
||||
@@ -840,7 +847,7 @@ namespace keepass2android
|
||||
{
|
||||
if (!_showPassword.ContainsKey(protectedTextView))
|
||||
{
|
||||
_showPassword[protectedTextView] = fieldKey == UpdateTotpTimerTask.TotpKey ? _showTotpDefault : _showPasswordDefault;
|
||||
_showPassword[protectedTextView] = fieldKey == Kp2aTotp.TotpKey ? _showTotpDefault : _showPasswordDefault;
|
||||
}
|
||||
var protectedTextviewGroup = new ProtectedTextviewGroup { ProtectedField = protectedTextView, VisibleProtectedField = visibleTextView};
|
||||
_protectedTextViews.Add(protectedTextviewGroup);
|
||||
@@ -946,24 +953,32 @@ namespace keepass2android
|
||||
|
||||
PopulateStandardText(Resource.Id.entry_user_name, Resource.Id.entryfield_container_username, PwDefs.UserNameField);
|
||||
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_totp, Resource.Id.entry_totp_visible }, Resource.Id.entryfield_container_totp, Kp2aTotp.TotpKey);
|
||||
PopulateStandardText(new List<int> { Resource.Id.entry_password, Resource.Id.entry_password_visible}, Resource.Id.entryfield_container_password, PwDefs.PasswordField);
|
||||
|
||||
RegisterProtectedTextView(PwDefs.PasswordField, FindViewById<TextView>(Resource.Id.entry_password), FindViewById<TextView>(Resource.Id.entry_password_visible));
|
||||
RegisterProtectedTextView(Kp2aTotp.TotpKey, FindViewById<TextView>(Resource.Id.entry_totp), FindViewById<TextView>(Resource.Id.entry_totp_visible));
|
||||
|
||||
RegisterTextPopup(FindViewById<RelativeLayout> (Resource.Id.groupname_container),
|
||||
FindViewById (Resource.Id.entry_group_name), KeyGroupFullPath);
|
||||
RegisterTextPopup(FindViewById<RelativeLayout> (Resource.Id.groupname_container),
|
||||
FindViewById (Resource.Id.entry_group_name), KeyGroupFullPath,
|
||||
FindViewById(Resource.Id.entryfield_group_container));
|
||||
|
||||
RegisterTextPopup(FindViewById<RelativeLayout>(Resource.Id.username_container),
|
||||
FindViewById(Resource.Id.username_vdots), PwDefs.UserNameField);
|
||||
FindViewById(Resource.Id.username_vdots), PwDefs.UserNameField,
|
||||
FindViewById(Resource.Id.entryfield_container_username));
|
||||
|
||||
RegisterTextPopup(FindViewById<RelativeLayout>(Resource.Id.url_container),
|
||||
FindViewById(Resource.Id.url_vdots), PwDefs.UrlField)
|
||||
FindViewById(Resource.Id.url_vdots), PwDefs.UrlField,
|
||||
FindViewById(Resource.Id.entryfield_container_url))
|
||||
.Add(new GotoUrlMenuItem(this, PwDefs.UrlField));
|
||||
RegisterTextPopup(FindViewById<RelativeLayout>(Resource.Id.password_container),
|
||||
FindViewById(Resource.Id.password_vdots), PwDefs.PasswordField);
|
||||
FindViewById(Resource.Id.password_vdots), PwDefs.PasswordField,
|
||||
FindViewById(Resource.Id.entryfield_container_password));
|
||||
RegisterTextPopup(FindViewById<RelativeLayout>(Resource.Id.totp_container),
|
||||
FindViewById(Resource.Id.totp_vdots), Kp2aTotp.TotpKey, FindViewById(Resource.Id.entryfield_container_totp));
|
||||
|
||||
|
||||
PopulateText(Resource.Id.entry_created, Resource.Id.entryfield_container_created, getDateTime(Entry.CreationTime));
|
||||
PopulateText(Resource.Id.entry_created, Resource.Id.entryfield_container_created, getDateTime(Entry.CreationTime));
|
||||
PopulateText(Resource.Id.entry_modified, Resource.Id.entryfield_container_modified, getDateTime(Entry.LastModificationTime));
|
||||
|
||||
if (Entry.Expires)
|
||||
@@ -977,7 +992,8 @@ namespace keepass2android
|
||||
}
|
||||
PopulateStandardText(Resource.Id.entry_comment, Resource.Id.entryfield_container_comment, PwDefs.NotesField);
|
||||
RegisterTextPopup(FindViewById<RelativeLayout>(Resource.Id.comment_container),
|
||||
FindViewById(Resource.Id.comment_vdots), PwDefs.NotesField);
|
||||
FindViewById(Resource.Id.comment_vdots), PwDefs.NotesField,
|
||||
FindViewById(Resource.Id.entryfield_container_comment));
|
||||
|
||||
PopulateText(Resource.Id.entry_tags, Resource.Id.entryfield_container_tags, concatTags(Entry.Tags));
|
||||
PopulateText(Resource.Id.entry_override_url, Resource.Id.entryfield_container_overrideurl, Entry.OverrideUrl);
|
||||
@@ -990,6 +1006,40 @@ namespace keepass2android
|
||||
|
||||
SetPasswordStyle();
|
||||
}
|
||||
|
||||
private async Task UpdateTotpCountdown()
|
||||
{
|
||||
if (App.Kp2a.LastOpenedEntry == null)
|
||||
return;
|
||||
var totpData = new Kp2aTotp().TryGetTotpData(App.Kp2a.LastOpenedEntry);
|
||||
|
||||
if (totpData == null || !totpData.IsTotpEntry)
|
||||
return;
|
||||
|
||||
var totpProvider = new TOTPProvider(totpData);
|
||||
|
||||
var progressBar = FindViewById<ProgressBar>(Resource.Id.TotpCountdownProgressBar);
|
||||
|
||||
int lastSecondsLeft = -1;
|
||||
while (!isPaused && progressBar != null)
|
||||
{
|
||||
|
||||
int secondsLeft = totpProvider.Timer;
|
||||
|
||||
if (secondsLeft != lastSecondsLeft)
|
||||
{
|
||||
lastSecondsLeft = secondsLeft;
|
||||
// Update the progress bar on the UI thread
|
||||
RunOnUiThread(() =>
|
||||
{
|
||||
progressBar.Progress = secondsLeft;
|
||||
progressBar.Max = totpProvider.Duration;
|
||||
});
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulatePreviousVersions()
|
||||
{
|
||||
@@ -1040,12 +1090,12 @@ namespace keepass2android
|
||||
SendBroadcast(i);
|
||||
}
|
||||
}
|
||||
private List<IPopupMenuItem> RegisterTextPopup(View container, View anchor, string fieldKey)
|
||||
private List<IPopupMenuItem> RegisterTextPopup(View container, View anchor, string fieldKey, View outerContainer)
|
||||
{
|
||||
return RegisterTextPopup(container, anchor, fieldKey, Entry.Strings.GetSafe(fieldKey).IsProtected);
|
||||
return RegisterTextPopup(container, anchor, fieldKey, Entry.Strings.GetSafe(fieldKey).IsProtected || fieldKey == Kp2aTotp.TotpKey, outerContainer);
|
||||
}
|
||||
|
||||
private List<IPopupMenuItem> RegisterTextPopup(View container, View anchor, string fieldKey, bool isProtected)
|
||||
private List<IPopupMenuItem> RegisterTextPopup(View container, View anchor, string fieldKey, bool isProtected, View outerContainer)
|
||||
{
|
||||
string popupKey = Strings.PrefixString + fieldKey;
|
||||
var popupItems = RegisterPopup(
|
||||
@@ -1055,10 +1105,20 @@ namespace keepass2android
|
||||
popupItems.Add(new CopyToClipboardPopupMenuIcon(this, _stringViews[fieldKey], isProtected));
|
||||
if (isProtected)
|
||||
{
|
||||
var valueView = container.FindViewById<TextView>(fieldKey == PwDefs.PasswordField ? Resource.Id.entry_password : Resource.Id.entry_extra);
|
||||
var valueView = container.FindViewById<TextView>(fieldKey switch
|
||||
{
|
||||
PwDefs.PasswordField => Resource.Id.entry_password,
|
||||
Kp2aTotp.TotpKey => Resource.Id.entry_totp,
|
||||
_ => Resource.Id.entry_extra
|
||||
});
|
||||
popupItems.Add(new ToggleVisibilityPopupMenuItem(this, valueView));
|
||||
}
|
||||
|
||||
//copy text to clipboard when the outer container (including the field icon on the left) or the inner container
|
||||
// (containing the textview and the vertical dots for the popup menu) is long-clicked.
|
||||
RegisterCopyOnLongClick(outerContainer, fieldKey, isProtected);
|
||||
RegisterCopyOnLongClick(container, fieldKey, isProtected);
|
||||
|
||||
if (fieldKey != PwDefs.UrlField //url already has a go-to-url menu
|
||||
&& (_stringViews[fieldKey].Text.StartsWith(KeePass.AndroidAppScheme)
|
||||
|| _stringViews[fieldKey].Text.StartsWith("http://")
|
||||
@@ -1069,6 +1129,11 @@ namespace keepass2android
|
||||
return popupItems;
|
||||
}
|
||||
|
||||
private void RegisterCopyOnLongClick(View container, string fieldKey, bool isProtected)
|
||||
{
|
||||
container.LongClick += (sender, args) =>
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(this, _stringViews[fieldKey].Text, isProtected);
|
||||
}
|
||||
|
||||
|
||||
private void ShowPopup(View anchor, string popupKey)
|
||||
@@ -1135,6 +1200,8 @@ namespace keepass2android
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, App.Kp2a.CurrentDb.KpDatabase, SprCompileFlags.All));
|
||||
PopulateText(viewIds, containerViewId, value);
|
||||
_stringViews.Add(key, new StandardStringView(viewIds, containerViewId, this));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void PopulateGroupText(int viewId, int containerViewId, String key)
|
||||
@@ -1282,11 +1349,16 @@ namespace keepass2android
|
||||
return base.OnPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
bool isPaused = false;
|
||||
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
private void UpdateTogglePasswordMenu()
|
||||
|
||||
private void UpdateTogglePasswordMenu()
|
||||
{
|
||||
IMenuItem togglePassword = _menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||
if (_showPassword.Values.All(x => x))
|
||||
@@ -1323,7 +1395,9 @@ namespace keepass2android
|
||||
ClearCache();
|
||||
base.OnResume();
|
||||
_activityDesign.ReapplyTheme();
|
||||
}
|
||||
isPaused = false;
|
||||
Task.Run(UpdateTotpCountdown);
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
|
@@ -39,6 +39,9 @@ using Android.Support.V4.View;
|
||||
using Android.Views.Autofill;
|
||||
using CursorAdapter = Android.Support.V4.Widget.CursorAdapter;
|
||||
using Object = Java.Lang.Object;
|
||||
using Android.Text;
|
||||
using keepass2android.search;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -115,6 +118,8 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = (showAddGroup || showAddEntry) ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = (showAddGroup || showAddEntry) ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabTotpOverview).Visibility = CanShowTotpFab() ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.insert_element, false);
|
||||
@@ -262,6 +267,7 @@ namespace keepass2android
|
||||
private bool hasCalledOtherActivity = false;
|
||||
private IMenuItem searchItem;
|
||||
private IMenuItem searchItemDummy;
|
||||
private bool isPaused;
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
@@ -281,8 +287,39 @@ namespace keepass2android
|
||||
RefreshIfDirty();
|
||||
|
||||
SetSearchItemVisibility();
|
||||
}
|
||||
|
||||
isPaused = false;
|
||||
System.Threading.Tasks.Task.Run(UpdateTotpCountdown);
|
||||
}
|
||||
private async System.Threading.Tasks.Task UpdateTotpCountdown()
|
||||
{
|
||||
|
||||
while (!isPaused )
|
||||
{
|
||||
RunOnUiThread(() =>
|
||||
{
|
||||
var listView = FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment)
|
||||
.ListView;
|
||||
if (listView != null)
|
||||
{
|
||||
int count = listView.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var item = listView.GetChildAt(i);
|
||||
if (item is PwEntryView)
|
||||
{
|
||||
var entryView = (PwEntryView)item;
|
||||
entryView.UpdateTotp();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await System.Threading.Tasks.Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInfotexts()
|
||||
{
|
||||
@@ -390,6 +427,13 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
|
||||
private void UpdatePostNotificationsPermissionInfo(bool hideForever=false)
|
||||
{
|
||||
const string prefsKey = "DidShowNotificationPermissionInfo";
|
||||
@@ -572,6 +616,25 @@ namespace keepass2android
|
||||
};
|
||||
}
|
||||
|
||||
if (FindViewById(Resource.Id.fabSearch) != null)
|
||||
{
|
||||
FindViewById(Resource.Id.fabSearch).Click += (sender, args) =>
|
||||
{
|
||||
if (searchView?.Iconified != false)
|
||||
ActivateSearchView();
|
||||
else
|
||||
searchView.Iconified = true;
|
||||
};
|
||||
}
|
||||
|
||||
if (FindViewById(Resource.Id.fabTotpOverview) != null)
|
||||
{
|
||||
FindViewById(Resource.Id.fabTotpOverview).Click += (sender, args) =>
|
||||
{
|
||||
SearchTotpResults.Launch(this, this.AppTask);
|
||||
};
|
||||
}
|
||||
|
||||
if (FindViewById(Resource.Id.fabCancelAddNew) != null)
|
||||
{
|
||||
FindViewById(Resource.Id.fabAddNew).Click += (sender, args) =>
|
||||
@@ -580,6 +643,8 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = AddGroupEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = AddEntryEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabTotpOverview).Visibility = ViewStates.Gone;
|
||||
};
|
||||
|
||||
FindViewById(Resource.Id.fabCancelAddNew).Click += (sender, args) =>
|
||||
@@ -588,6 +653,8 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Visible;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Visible;
|
||||
FindViewById(Resource.Id.fabTotpOverview).Visibility = CanShowTotpFab() ? ViewStates.Visible : ViewStates.Gone;
|
||||
};
|
||||
|
||||
|
||||
@@ -667,7 +734,12 @@ namespace keepass2android
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected virtual bool CanShowTotpFab()
|
||||
{
|
||||
return App.Kp2a.CurrentDb.HasTotpEntries && Group == App.Kp2a.CurrentDb.Root;
|
||||
}
|
||||
|
||||
private bool IsTimeForInfotext(out string lastInfoText)
|
||||
{
|
||||
DateTime lastDisplayTime = new DateTime(_prefs.GetLong("LastInfoTextTime", 0));
|
||||
@@ -1028,6 +1100,7 @@ namespace keepass2android
|
||||
|
||||
searchView.Iconified = false;
|
||||
AppTask.CanActivateSearchViewOnStart = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1067,6 +1140,15 @@ namespace keepass2android
|
||||
|
||||
public abstract ElementAndDatabaseId FullGroupId { get; }
|
||||
|
||||
public virtual bool MayPreviewTotp
|
||||
{
|
||||
get
|
||||
{
|
||||
return !PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.masktotp_key),
|
||||
Resources.GetBoolean(Resource.Boolean.masktotp_default));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool OnPrepareOptionsMenu(IMenu menu)
|
||||
{
|
||||
@@ -1267,6 +1349,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Gone;
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.insert_element, true);
|
||||
UpdateBottomBarElementVisibility(Resource.Id.cancel_insert_element, true);
|
||||
@@ -1330,6 +1413,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
ListView.ItemClick += (sender, args) => ((GroupListItemView)args.View).OnClick();
|
||||
|
||||
|
||||
StyleListView();
|
||||
|
||||
|
@@ -140,7 +140,7 @@ namespace keepass2android
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof (SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new SearchUrlTask() {UrlToSearchFor = _requestedUrl, ShowUserNotifications = ShowUserNotificationsMode.WhenTotp};
|
||||
var task = new SearchUrlTask() {UrlToSearchFor = _requestedUrl, ShowUserNotifications = ActivationCondition.WhenTotp, ActivateKeyboard = ActivationCondition.Never };
|
||||
task.ToIntent(i);
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
_startedQuery = true;
|
||||
|
BIN
src/keepass2android/Resources/drawable-mdpi/ic_entry_totp.png
Normal file
BIN
src/keepass2android/Resources/drawable-mdpi/ic_entry_totp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_search.png
Normal file
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_totp.png
Normal file
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_totp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_entry_totp.png
Normal file
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_entry_totp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_search.png
Normal file
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_totp.png
Normal file
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_totp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
@@ -61,6 +61,28 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:text="group detail"
|
||||
style="@style/GroupDetailInSearchResult" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/totp_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/totp_text"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:text=""/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/TotpCountdownProgressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="30dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView android:id="@+id/right_arrow"
|
||||
|
@@ -184,6 +184,68 @@
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/entryfield_container_totp"
|
||||
style="@style/EntryEditSingleLine_container">
|
||||
<ImageView
|
||||
style="@style/EntryEditSingleLine_ImageView"
|
||||
android:src="@drawable/ic_entry_totp" />
|
||||
|
||||
<LinearLayout
|
||||
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:orientation="vertical">
|
||||
<!-- TOTP -->
|
||||
<TextView
|
||||
android:id="@+id/entry_totp_label"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/TOTP"
|
||||
style="@style/EntryFieldHeader" />
|
||||
<RelativeLayout
|
||||
android:id="@+id/totp_container"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:orientation="horizontal"
|
||||
android:clickable="true"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
<ImageView
|
||||
android:id="@+id/totp_vdots"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="15dp"
|
||||
android:src="@drawable/vdots"
|
||||
android:gravity="right|bottom"
|
||||
android:layout_alignParentRight="true" />
|
||||
<TextView
|
||||
android:id="@+id/entry_totp"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:password="true"
|
||||
android:typeface="monospace"
|
||||
android:layout_toLeftOf="@id/totp_vdots"
|
||||
style="@style/EntryItem" />
|
||||
<TextView
|
||||
android:id="@+id/entry_totp_visible"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toLeftOf="@id/totp_vdots"
|
||||
style="@style/EntryItem" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/TotpCountdownProgressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="30dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/entryfield_container_comment"
|
||||
style="@style/EntryEditSingleLine_container">
|
||||
|
@@ -400,5 +400,23 @@
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="160dp"
|
||||
android:visibility="gone"/>
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fabSearch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom|right"
|
||||
android:src="@drawable/ic_fab_search"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="88dp"
|
||||
android:visibility="gone"/>
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fabTotpOverview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom|right"
|
||||
android:src="@drawable/ic_fab_totp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="160dp"
|
||||
android:visibility="gone"/>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
</RelativeLayout>
|
@@ -541,7 +541,9 @@
|
||||
<string name="filestoragename_gdrive">Google Drive</string>
|
||||
<string name="filestoragename_gdriveKP2A">Google Drive (archivos KP2A)</string>
|
||||
<string name="filestoragehelp_gdriveKP2A">Si no deseas brindarle acceso completo a KP2A para acceder a todos los archivos en Google Drive, debes seleccionar esta opción. Recuerda que primero debes crear una base de datos y los archivos existentes no son visibles para la aplicación. Selecciona esta opción desde la pantalla de \"Crear una base de datos\" o, si ya abriste una base de datos, puedes exportarla seleccionando esta opción.</string>
|
||||
<string name="filestoragename_pcloud">PCloud (carpeta de KP2A)</string>
|
||||
<string name="filestoragehelp_pcloud">Este tipo de almacenamiento sólo solicitará acceso a la carpeta de pCloud \"Aplicaciones/Keepass2Android\". Si desea utilizar una base de datos existente de su cuenta pCloud, asegúrese de que el archivo se coloca en dicha carpeta de pCloud.</string>
|
||||
<string name="filestoragename_pcloudall">PCloud (acceso sin restricciones)</string>
|
||||
<string name="filestoragename_onedrive">OneDrive</string>
|
||||
<string name="filestoragename_onedrive2">OneDrive</string>
|
||||
<string name="filestoragename_onedrive2_full">Todos los archivos y archivos compartidos</string>
|
||||
@@ -593,6 +595,7 @@
|
||||
<string name="TrayTotp_prefs">TrayTotp</string>
|
||||
<string name="DebugLog_prefs_prefs">Fichero registro para Depuración</string>
|
||||
<string name="DebugLog_title">Usar el archivo de registro</string>
|
||||
<string name="FtpDebug_title">Registro de depuración FTP/SFTP</string>
|
||||
<string name="DebugLog_summary">Escribir salida de app a fichero local de log</string>
|
||||
<string name="DebugLog_send">Enviar registro de depuración...</string>
|
||||
<string name="loading">Cargando…</string>
|
||||
@@ -661,6 +664,15 @@
|
||||
<string name="Continue">Continuar</string>
|
||||
<string name="NoFilenameWarning">El URI que ha introducido no parece ser un nombre de archivo. ¿Está seguro que es un archivo válido?</string>
|
||||
<string name="FirstInvalidCompositeKeyError">Clave compuesta no válida! Por favor, inténtelo de nuevo.</string>
|
||||
<string name="RepeatedInvalidCompositeKeyHelp">¡Clave compuesta incorrecta! Por favor, sigue los siguientes pasos para desbloquear la Base de Datos:\n
|
||||
|
||||
• Asegúrate de haber puesto la contraseña correcta. Utiliza el icono del ojo para ver la contraseña.\n
|
||||
• Asegúrate de haber seleccionado el tipo de contraseña correcta. Debe coincidir con el tipo usado al crear la Base de Datos.\n
|
||||
• Asegúrate de haber seleccionado la Base de Datos correcta.
|
||||
</string>
|
||||
<string name="HintLocalBackupInvalidCompositeKey"> \n
|
||||
• Sugerencia: Si piensas que la Base de Datos está dañada o no recuerdas la contraseña maestra después de cambiarla, inténtalo con la última versión de la Base de Datos abierta con éxito pulsando en \"%1$s\" y seleccionando la copia local.
|
||||
</string>
|
||||
<string name="open_other_db">Abrir otrar base de datos…</string>
|
||||
<string name="select_database">Seleccione base de datos</string>
|
||||
<string name="configure_child_dbs">Configure bases de datos hijas…</string>
|
||||
|
@@ -402,6 +402,14 @@
|
||||
<string name="ShowSeparateNotifications_summary">ユーザー名やパスワードをクリップボードへコピーするための通知とキーボード変更のための通知を分割して表示します。</string>
|
||||
<string name="AccServiceAutoFill_prefs">自動入力ユーザー補助サービス</string>
|
||||
<string name="AutoFill_prefs">自動入力サービス</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">TOTP を含むエントリーを自動入力する場合、TOTP をコピーボタンをエントリーの通知に表示します</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">エントリーの通知を表示</string>
|
||||
<string name="AutoFillTotp_prefs_title">TOTP エントリーの自動入力</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">クリップボードに TOTP をコピー</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">TOTP を含むエントリーを自動入力する場合、 クリップボードに TOTP をコピーします</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">TOTP を含むエントリーを自動入力する場合、TOTP ボタン付きの内蔵キーボードを起動します。</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">内蔵キーボードを起動</string>
|
||||
<string name="TotpCopiedToClipboard">クリップボードに TOTP をコピーしました</string>
|
||||
<string name="ShowKp2aKeyboardNotification_title">KP2A キーボードの通知</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">KP2A のキーボードからすべてのエントリーにアクセスできるようにします (推奨)</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">キーボード切り替え</string>
|
||||
@@ -589,6 +597,7 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">KeePass 2.x (PC) の KeeChallenge プラグインを使用して、チャレンジレスポンスを使うようにデータベースを構成してください!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">OTP 補助ファイルの更新にエラーが発生しました!</string>
|
||||
<string name="TrayTotp_SeedField_title">TOTP シード フィールド名</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">デフォルト以外の設定で Keepass 2 プラグイン「TrayTotp」を使用している場合、PC での設定に従ってシード フィールドのフィールド名を入力してください。</string>
|
||||
<string name="TrayTotp_SettingsField_title">TOTP 設定フィールド名</string>
|
||||
<string name="TrayTotp_SettingsField_summary">ここに TrayTotp の設定フィールドのフィールド名を入力してください。</string>
|
||||
|
@@ -2,8 +2,8 @@
|
||||
<!--Generated by crowdin.net-->
|
||||
<resources>
|
||||
<string name="about_feedback">Terugkoppeling</string>
|
||||
<string name="AboutText">Keepass2Android is een wachtwoordmanager voor Android die KeePass 2.x databases kan lezen en schrijven.</string>
|
||||
<string name="CreditsText">De gebruikersinterface is gebaseerd op KeepassDroid, een port ontwikkeld door Brian Pellin. Code voor de database operaties is gebaseerd op KeePass door Dominik Reichl. De Android robot is gereproduceerd of aangepast van werk gemaakt en gedeeld door Google en gebruikt in overeenstemming met de voorwaarden beschreven in de Creative Commons 3.0 Attribution License.</string>
|
||||
<string name="AboutText">Keepass2Android is een wachtwoordbeheerder die lees-/schrijftoegang biedt tot KeePass 2.x-databases op Android.</string>
|
||||
<string name="CreditsText">De gebruikersinterface is gebaseerd op een port van KeepassDroid ontwikkeld door Brian Pellin. De code voor databasebewerkingen is gebaseerd op KeePass van Dominik Reichl. De Android robot is gereproduceerd of aangepast van werk gemaakt en gedeeld door Google en gebruikt volgens de voorwaarden beschreven in de Creative Commons 3.0 Naamsvermelding Licentie.</string>
|
||||
<string name="CreditsTextSFTP">SFTP ondersteuning is geïmplementeerd door middel van de JSch-bibliotheek onder BSD-licentie, gemaakt door JCraft, Inc.</string>
|
||||
<string name="CreditsIcons">Het hamer-pictogram is gemaakt door John Caserta van het Noun Project. Het pinguïn-pictogram is gemaakt door Adriano Emerick van het Noun Project. Het veer-pictogram is gemaakt door Jon Testa van het Noun Project. Het Apple-pictogram is gemaakt door Ava Rowell van het Noun Project. Het afbeelding-pictogram komt van https://icons8.com/icon/5570/Picture.</string>
|
||||
<string name="accept">Accepteren</string>
|
||||
@@ -20,20 +20,20 @@
|
||||
<string name="short_app_name">KP2A</string>
|
||||
<string name="app_name_nonet">Keepass2Android Offline</string>
|
||||
<string name="short_app_name_nonet">KP2A Offline</string>
|
||||
<string name="app_timeout">App timeout</string>
|
||||
<string name="app_timeout_summary">Tijd tot het vergrendelen van de database bij inactiviteit van de app.</string>
|
||||
<string name="app_timeout">App time-out</string>
|
||||
<string name="app_timeout_summary">Tijd voordat de database wordt vergrendeld als de app inactief is.</string>
|
||||
<string name="show_kill_app">Sluiten-Knop</string>
|
||||
<string name="kill_app_label">App-proces afsluiten</string>
|
||||
<string name="show_kill_app_summary">Een knop weergeven in het wachtwoordscherm om de applicatie te beëindigen (voor paranoïde gebruikers)</string>
|
||||
<string name="show_kill_app_summary">Toon een knop in het wachtwoordscherm om het app-proces te beëindigen (voor paranoïde gebruikers)</string>
|
||||
<string name="application">App</string>
|
||||
<string name="application_settings">App-instellingen</string>
|
||||
<string name="ShowGroupnameInSearchResult_title">Toon groepsnaam in zoekresultaat</string>
|
||||
<string name="ShowGroupnameInSearchResult_resume">Toon groepsnaam onder item namen in zoekresultaten. Handig als verschillende items dezelfde naam hebben.</string>
|
||||
<string name="NavigationToGroupCompleted_message">Getoonde groep is nu: %1$s</string>
|
||||
<string name="AutofillDisabledQueriesPreference_title">Automatisch invullen is uitgeschakeld voor</string>
|
||||
<string name="AutofillDisabledQueriesPreference_summary">Toont een lijst van apps en websites waarvoor automatisch invullen is uitgeschakeld</string>
|
||||
<string name="OfferSaveCredentials_summary">Indien ingeschakeld, zal Android vragen of je de gegevens wilt opslaan nadat je handmatig gegevens hebt aangepast in auto-vulbare velden.</string>
|
||||
<string name="OfferSaveCredentials_title">Bied het opslaan van wachtwoordgegevens aan</string>
|
||||
<string name="AutofillDisabledQueriesPreference_summary">Toont een lijst van apps en websites waarvoor Automatisch Invullen is uitgeschakeld</string>
|
||||
<string name="OfferSaveCredentials_summary">Bij inschakelen vraagt Android of je gegevens wilt opslaan nadat je handmatig gegevens hebt ingevoerd in automatisch invulbare velden.</string>
|
||||
<string name="OfferSaveCredentials_title">Opslaan van wachtwoordgegevens aanbieden</string>
|
||||
<string name="ShowGroupInEntry_title">Toon groepsnaam in item venster</string>
|
||||
<string name="unknown_uri_scheme">Sorry! Keepass2Android kan niet overweg met de ontvangen URI %1$s. Neem contact op met de ontwikkelaar!</string>
|
||||
<string name="Entry_singular">Eén item</string>
|
||||
@@ -43,29 +43,29 @@
|
||||
<string name="security_prefs">Beveiliging</string>
|
||||
<string name="display_prefs">Weergave</string>
|
||||
<string name="password_access_prefs">Wachtwoordtoegang</string>
|
||||
<string name="QuickUnlock_prefs">Snel Openen</string>
|
||||
<string name="FileHandling_prefs">Omgang met bestanden</string>
|
||||
<string name="QuickUnlock_prefs">SnelOpenen</string>
|
||||
<string name="FileHandling_prefs">Bestandsbeheer</string>
|
||||
<string name="keyboard_prefs">Toetsenbord</string>
|
||||
<string name="export_prefs">Database exporteren...</string>
|
||||
<string name="fingerprint_prefs">Ontgrendelen met biometrie</string>
|
||||
<string name="import_db_prefs">Database importeren naar interne map</string>
|
||||
<string name="import_keyfile_prefs">Sleutelbestand importeren</string>
|
||||
<string name="export_keyfile_prefs">Exporteer sleutelbestand vanuit interne map</string>
|
||||
<string name="import_keyfile_prefs">Sleutelbestand naar interne map importeren</string>
|
||||
<string name="export_keyfile_prefs">Sleutelbestand vanuit interne map exporteren</string>
|
||||
<string name="keyboardswitch_prefs">Toetsenbord wisselen</string>
|
||||
<string name="OnlyAvailableForLocalFiles">Alleen beschikbaar voor lokale bestanden.</string>
|
||||
<string name="FileIsInInternalDirectory">Bestand is opgeslagen in interne map.</string>
|
||||
<string name="DatabaseFileMoved">De database is geïmporteerd. Druk op Oké om de database te openen van de nieuwe locatie. Let op: Vergeet niet om regelmatig de database te exporteren!</string>
|
||||
<string name="KeyfileMoved">Sleutelbestand geïmporteerd. Zorg voor een back-up voordat je het bestand verwijdert!</string>
|
||||
<string name="KeyfileMoveRequiresRememberKeyfile">Om de interne map te gebruiken moet de locatie van het sleutelbestand bewaard blijven. Pas uw beveiligingsinstellingen aan.</string>
|
||||
<string name="DatabaseFileMoved">Database is gekopieerd naar interne map. Met Ok kunt u het bestand openen vanaf de nieuwe locatie. NB: Vergeet niet de database regelmatig naar een veilige opslagplaats te exporteren!</string>
|
||||
<string name="KeyfileMoved">Sleutelbestand is gekopieerd naar interne map. Maak een veilige back-up voordat het bestand is verwijderd van de huidige locatie!</string>
|
||||
<string name="KeyfileMoveRequiresRememberKeyfile">Om de interne map te gebruiken moet de locatie van het sleutelbestand bewaard blijven. Pas de beveiligingsinstellingen aan.</string>
|
||||
<string name="unlock_database_button">Openen</string>
|
||||
<string name="unlock_database_title">Database openen</string>
|
||||
<string name="brackets">Haakjes</string>
|
||||
<string name="cancel">Annuleren</string>
|
||||
<string name="Ok">Oké</string>
|
||||
<string name="Ok">Ok</string>
|
||||
<string name="disable_sensor">Sensor uitschakelen</string>
|
||||
<string name="enable_sensor">Sensor inschakelen</string>
|
||||
<string name="ClearClipboard">Klembord gewist.</string>
|
||||
<string name="clipboard_timeout">Klembordtimeout</string>
|
||||
<string name="clipboard_timeout">Klembord time-out</string>
|
||||
<string name="clipboard_timeout_summary">Tijd tussen het kopiëren van gebruikersnaam of wachtwoord en het wissen van het klembord</string>
|
||||
<string name="copy_username">Selecteer om gebruikersnaam naar klembord te kopiëren</string>
|
||||
<string name="copy_password">Selecteer om wachtwoord naar klembord te kopiëren</string>
|
||||
@@ -80,11 +80,11 @@
|
||||
<string name="current_group_root">Huidige groep: Root</string>
|
||||
<string name="database">Database</string>
|
||||
<string name="digits">Cijfers</string>
|
||||
<string name="disclaimer_formal">Keepass2Android biedt GEEN ENKELE GARANTIE; Dit is gratis software, je mag deze software verspreiden onder de voorwaarden van de GPL versie 2 of recenter.</string>
|
||||
<string name="disclaimer_formal">Keepass2Android biedt GEEN ENKELE GARANTIE; Dit is gratis software, je mag dhet verspreiden onder de voorwaarden van de GPL versie 2 of recenter.</string>
|
||||
<string name="ellipsis">\u2026</string>
|
||||
<string name="copy_to_clipboard">Kopieer naar klembord</string>
|
||||
<string name="SystemLanguage">Systeemtaal</string>
|
||||
<string name="fingerprint_description">Verifiëren om door te gaan</string>
|
||||
<string name="fingerprint_description">Authenticeer om door te gaan</string>
|
||||
<string name="fingerprint_fatal">Biometrische ontgrendeling kan niet worden ingesteld:</string>
|
||||
<string name="fingerprint_not_recognized">Biometrische authenticatie mislukt. Probeer opnieuw.</string>
|
||||
<string name="fingerprint_success">Biometrische authenticatie geslaagd</string>
|
||||
@@ -93,15 +93,15 @@
|
||||
<string name="fingerprint_no_enrolled">Je hebt biometrische authenticatie nog niet geconfigureerd op dit apparaat. Ga eerst naar de systeeminstellingen.</string>
|
||||
<string name="disable_fingerprint_unlock">Biometrische ontgrendeling uitschakelen</string>
|
||||
<string name="enable_fingerprint_unlock">Volledige Biometrische ontgrendeling inschakelen</string>
|
||||
<string name="enable_fingerprint_quickunlock">Biometrische ontgrendeling voor QuickUnlock inschakelen</string>
|
||||
<string name="fingerprint_unlock_failed">Biometrische Ontgrendel is mislukt. Decryptie sleutel is ongeldig gemaakt door Android OS. Dit gebeurt meestal als biometrische authenticatie of veiligheidsinstellingen zijn gewijzigd. </string>
|
||||
<string name="fingerprint_disabled_wrong_masterkey">Ontgrendelen van de database mislukt: Ongeldige sleutel. Biometrische ontgrendelen is uitgeschakeld omdat het hoofdwachtwoord niet meer geldig is. </string>
|
||||
<string name="enable_fingerprint_quickunlock">Biometrische ontgrendeling voor SnelOpenen inschakelen</string>
|
||||
<string name="fingerprint_unlock_failed">Biometrische ontgrendeling is mislukt. Ontcijferingssleutel is ongeldig gemaakt door Android OS. Dit gebeurt meestal als biometrische authenticatie of veiligheidsinstellingen werden gewijzigd. </string>
|
||||
<string name="fingerprint_disabled_wrong_masterkey">Ontgrendelen van de database mislukt: Ongeldige samengestelde sleutel. Biometrische ontgrendeling is uitgeschakeld omdat het opgeslagen hoofdwachtwoord blijkbaar niet langer geldig is.</string>
|
||||
<string name="fingerprint_reenable">Schakel de Biometrische ontgrendeling opnieuw in voor het nieuwe hoofdwachtwoord.</string>
|
||||
<string name="fingerprint_reenable2">Ontgrendelen met jouw wachtwoord, schakel daarna de Biometrische ontgrendeling opnieuw in in de instellingen van de database.</string>
|
||||
<string name="FingerprintInitFailed">Mislukt om biometrische authenticatie te initialiseren. </string>
|
||||
<string name="fingerprint_reenable2">Ontgrendel met je wachtwoord en schakel Biometrische ontgrendeling opnieuw in bij de database-instellingen.</string>
|
||||
<string name="FingerprintInitFailed">Initialiseren biometrische authenticatie faalde. </string>
|
||||
<string name="FingerprintSetupFailed">Kan gegevens niet versleutelen. Dit kan gebeuren als je vingerafdrukken toevoegt of verwijdert in de systeeminstellingen terwijl Keepass2Android luistert naar je vingerafdruk.</string>
|
||||
<string name="enable_fingerprint_unlock_Info">Dit zal je hoofdwachtwoord op dit apparaat opslaan. Het wordt versleuteld door de Android Keystore en beschermd door authenticatie met jouw vingerafdruk. Dit geeft de mogelijkheid de database enkel met jouw vingerafdruk te ontgrendelen.</string>
|
||||
<string name="enable_fingerprint_quickunlock_Info">Gebruik biometrische authenticatie in plaats van de QuickUnlock code. Dit slaat geen informatie op die gerelateerd is aan je hoofdwachtwoord.</string>
|
||||
<string name="enable_fingerprint_unlock_Info">Dit zal je hoofdwachtwoord op dit apparaat opslaan. Het wordt versleuteld door de Android Keystore en beschermd door biometrische authenticatie. Dit geeft de mogelijkheid de database enkel met jouw vingerafdruk te ontgrendelen.</string>
|
||||
<string name="enable_fingerprint_quickunlock_Info">Maakt het mogelijk om biometrische authenticatie te gebruiken in plaats van de SnelOpenen-code. Slaat geen informatie over het hoofdwachtwoord op.</string>
|
||||
<string name="enter_filename">Voer databasebestandsnaam in</string>
|
||||
<string name="entry_accessed">Geopend op</string>
|
||||
<string name="entry_cancel">Annuleren</string>
|
||||
@@ -152,6 +152,7 @@
|
||||
<string name="hint_keyfile">sleutelbestand</string>
|
||||
<string name="hint_length">lengte</string>
|
||||
<string name="hint_pass">wachtwoord</string>
|
||||
<string name="hint_keyfile_path">SSH-privésleutel pad</string>
|
||||
<string name="hint_login_pass">Wachtwoord</string>
|
||||
<string name="hint_title">naam</string>
|
||||
<string name="hint_url">URL</string>
|
||||
@@ -314,26 +315,26 @@
|
||||
<string name="start_create_import">Bestand importeren naar nieuwe database...</string>
|
||||
<string name="enter_filename_details_url">De volledige URL moet worden opgegeven inclusief protocol zoals http://.</string>
|
||||
<string name="enter_filename_details_create_import">Te importeren bestand zal in de volgende stap geselecteerd worden.</string>
|
||||
<string name="enable_quickunlock">Snel Openen inschakelen</string>
|
||||
<string name="QuickUnlock_label">Voer de laatste %1$d karakters van je wachtwoord in:</string>
|
||||
<string name="QuickUnlock_label_secure">Snel Openen code invoeren:</string>
|
||||
<string name="QuickUnlock_button">Snel Openen!</string>
|
||||
<string name="enable_quickunlock">SnelOpenen inschakelen</string>
|
||||
<string name="QuickUnlock_label">Vul de laatste %1$d tekens van uw wachtwoord in:</string>
|
||||
<string name="QuickUnlock_label_secure">SnelOpenen code invoeren:</string>
|
||||
<string name="QuickUnlock_button">SnelOpenen!</string>
|
||||
<string name="QuickUnlock_lockButton">Database sluiten</string>
|
||||
<string name="QuickUnlockDefaultEnabled_title">Snel Openen standaard ingeschakeld</string>
|
||||
<string name="QuickUnlockDefaultEnabled_summary">Hiermee definieert u of Snel Openen standaard is ingeschakeld of niet.</string>
|
||||
<string name="QuickUnlockDefaultEnabled_title">SnelOpenen standaard inschakelen</string>
|
||||
<string name="QuickUnlockDefaultEnabled_summary">Bepaalt of SnelOpenen standaard is ingeschakeld of niet.</string>
|
||||
<string name="ViewDatabaseSecure_title">Bescherm weergeven database</string>
|
||||
<string name="ViewDatabaseSecure_summary">Wanneer ingeschakeld is het maken van screenshots niet toegestaan en zal geen miniatuur van de app worden weergegeven in de lijst met recente apps.</string>
|
||||
<string name="QuickUnlockIconHidden_title">Snel Openen pictogram verbergen</string>
|
||||
<string name="QuickUnlockIconHidden_summary">Snel Openen helaas werkt niet zonder een notificatiepictogram weer te geven. Selecteer deze optie om een transparant pictogram te gebruiken.</string>
|
||||
<string name="QuickUnlockIconHidden16_title">Snel Openen pictogram verbergen</string>
|
||||
<string name="QuickUnlockIconHidden16_summary">QuickUnlock vereist een notificatie om goed te werken. Selecteer deze optie om de notificatie pictogram niet te tonen.</string>
|
||||
<string name="QuickUnlockLength_title">Lengte van sleutel voor Snel Openen</string>
|
||||
<string name="QuickUnlockLength_summary">Maximum aantal tekens gebruikt voor Snel Openen wachtwoord.</string>
|
||||
<string name="QuickUnlockHideLength_title">Verberg Snel Openen lengte</string>
|
||||
<string name="QuickUnlockHideLength_summary">Als ingeschakeld, wordt de lengte van de Snel Openen code niet weergegeven in het Snel Openen scherm.</string>
|
||||
<string name="QuickUnlockKeyFromDatabase_title">Snelle deblokkeercode uit database item</string>
|
||||
<string name="QuickUnlockKeyFromDatabase_summary">Als de actieve database een item met titel QuickUnlock in de hoofdgroep bevat, wordt het wachtwoord van dit item gebruikt als snelle deblokkeer code.</string>
|
||||
<string name="QuickUnlock_fail">Snel Openen is mislukt: verkeerd wachtwoord!</string>
|
||||
<string name="QuickUnlockIconHidden_title">Verberg pictogram SnelOpenen</string>
|
||||
<string name="QuickUnlockIconHidden_summary">SnelOpenen werkt helaas niet zonder een meldingspictogram weer te geven. Kies deze optie om een transparant pictogram te gebruiken.</string>
|
||||
<string name="QuickUnlockIconHidden16_title">Verberg pictogram SnelOpenen</string>
|
||||
<string name="QuickUnlockIconHidden16_summary">SnelOpenen vereist een melding om juist te werken. Kies deze optie om een melding zonder pictogram weer te geven.</string>
|
||||
<string name="QuickUnlockLength_title">Lengte van SnelOpenen sleutel</string>
|
||||
<string name="QuickUnlockLength_summary">Maximum aantal tekens dat wordt gebruikt als SnelOpenen-wachtwoord.</string>
|
||||
<string name="QuickUnlockHideLength_title">Verberg SnelOpenen lengte</string>
|
||||
<string name="QuickUnlockHideLength_summary">Indien geactiveerd, wordt de lengte van de SnelOpenen code niet weergegeven op het SnelOpenen scherm.</string>
|
||||
<string name="QuickUnlockKeyFromDatabase_title">SnelOpenen sleutel uit database invoer</string>
|
||||
<string name="QuickUnlockKeyFromDatabase_summary">Als de actieve database een item bevat met de titel \"SnelOpenen\" in de hoofdgroep, wordt het wachtwoord van dit item gebruikt als SnelOpenen code.</string>
|
||||
<string name="QuickUnlock_fail">SnelOpenen is mislukt: wachtwoord onjuist!</string>
|
||||
<string name="SaveAttachmentDialog_title">Bijlage opslaan</string>
|
||||
<string name="SaveAttachmentDialog_text">Selecteer waar u de bijlage wilt opslaan.</string>
|
||||
<string name="SaveAttachmentDialog_save">Exporteer naar bestand...</string>
|
||||
@@ -360,7 +361,7 @@
|
||||
<string name="totp_length">Lengte van de code</string>
|
||||
<string name="totp_scan">Scan QR code</string>
|
||||
<string name="delete_extra_string">Extra waarde verwijderen</string>
|
||||
<string name="database_loaded_quickunlock_enabled">%1$s: vergrendeld. Snel Openen ingeschakeld.</string>
|
||||
<string name="database_loaded_quickunlock_enabled">%1$s: vergrendeld. SnelOpenen ingeschakeld.</string>
|
||||
<string name="database_loaded_unlocked">%1$s: Ontgrendeld.</string>
|
||||
<string name="credentials_dialog_title">Voer server inloggegevens in</string>
|
||||
<string name="UseFileTransactions_title">Bestandshandelingen</string>
|
||||
@@ -381,7 +382,7 @@
|
||||
<string name="NoDonationReminder_title">Nooit vragen om een donatie</string>
|
||||
<string name="NoDonationReminder_summary">Ik geef je nog geen dubbeltje of ik heb al gedoneerd. Niet vragen om een donatie, zelfs niet op de verjaardag van de auteur.</string>
|
||||
<string name="UseOfflineCache_title">Database caching</string>
|
||||
<string name="UseOfflineCache_summary">Houd een kopie van de database-bestanden in de cache-map van de app. Dit maakt het mogelijk om databases te gebruiken, zelfs als het database-bestand niet toegankelijk is.</string>
|
||||
<string name="UseOfflineCache_summary">Bewaar een kopie van de databasebestanden in de cache-map van de app. Dit maakt het mogelijk databases te gebruiken, zelfs als het databasebestand niet toegankelijk is.</string>
|
||||
<string name="CreateBackups_title">Lokale back-ups</string>
|
||||
<string name="CreateBackups_summary">Maak een lokale back-up na het goed openen van een database.</string>
|
||||
<string name="UpdatingBackup">Lokale back-up bijwerken...</string>
|
||||
@@ -401,6 +402,14 @@
|
||||
<string name="ShowSeparateNotifications_summary">Toon afzonderlijke notificaties voor het kopiëren van gebruikersnaam en wachtwoord en voor het inschakelen van het toetsenbord.</string>
|
||||
<string name="AccServiceAutoFill_prefs">Toegankelijkheid service voor automatisch invullen</string>
|
||||
<string name="AutoFill_prefs">Service voor automatisch invullen</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">Laat bij het automatisch invullen van een invoer met TOTP de invoer-melding zien met een knop Kopieer TOTP</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">Toon de invoer-melding</string>
|
||||
<string name="AutoFillTotp_prefs_title">Automatisch invullen voor TOTP-invoer</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">TOTP naar klembord kopiëren</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">Kopieer de TOTP naar het klembord bij het automatisch aanvullen met TOTP. </string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">Activeer het ingebouwde toetsenbord bij het automatisch invoeren van TOTP. Het toetsenbord heeft een TOTP-toets.</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">Activeer het ingebouwde toetsenbord</string>
|
||||
<string name="TotpCopiedToClipboard">TOTP naar klembord gekopieerd</string>
|
||||
<string name="ShowKp2aKeyboardNotification_title">KP2A toetsenbordmelding</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Maak het volledige item toegankelijk via het toetsenbord van de KP2A (aanbevolen).</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">Wissel toetsenbord</string>
|
||||
@@ -417,12 +426,13 @@
|
||||
<string name="ShowUnlockedNotification_summary">Toon doorlopend bericht terwijl de database ontgrendeld is.</string>
|
||||
<string name="IconVisibilityInfo_Android8_text">Android 8 introduceert nieuw gedrag voor meldingen. Als je het pictogram van Keepass2Android\'s meldingen wilt verbergen kunt je dit wijzigen in de systeeminstellingen. Stel de prioriteit van de meldingencategorie op het minimum in.</string>
|
||||
<string name="IconVisibilityInfo_Android8_btnSettings">Instellingen openen</string>
|
||||
<string name="PostNotificationsPermissionInfo_text">Keepass2Android kan het systeem een melding laten geven als uw database niet is vergrendeld. U moet voor deze functie toestemming geven.</string>
|
||||
<string name="DontCare">Maakt me niet uit</string>
|
||||
<string name="DocumentAccessRevoked">Dit bestand is niet meer toegangelijk voor Keepass2Android. Het is verwijderd of de toegangsrechten zijn ingetrokken. Probeer opnieuw te openen, bijv. met \'Wijzig database\'.</string>
|
||||
<string name="PreloadDatabaseEnabled_title">Pre-load van databasebestand</string>
|
||||
<string name="PreloadDatabaseEnabled_summary">Start laden op de achtergrond of het downloaden van het databasebestand tijdens het wachtwoord invoeren.</string>
|
||||
<string name="SyncAfterQuickUnlock_title">Synchroniseer na Snel Openen</string>
|
||||
<string name="SyncAfterQuickUnlock_summary">Synchroniseer de database met externe bestanden na het ontgrendelen met QuickUnlock.</string>
|
||||
<string name="SyncAfterQuickUnlock_title">Synchroniseer na SnelOpenen</string>
|
||||
<string name="SyncAfterQuickUnlock_summary">Synchroniseer database met extern bestand na ontgrendeling met SnelOpenen.</string>
|
||||
<string name="AskOverwriteBinary">Wil je het bestaande binaire bestand met dezelfde naam overschrijven?</string>
|
||||
<string name="AskOverwriteBinary_title">Overschrijf bestaande bestand?</string>
|
||||
<string name="AskOverwriteBinary_yes">Overschrijven</string>
|
||||
@@ -501,9 +511,27 @@
|
||||
<string name="hint_sftp_host">host (bijv: 192.168.0.1)</string>
|
||||
<string name="hint_sftp_port">poort</string>
|
||||
<string name="initial_directory">Initiële map (optioneel):</string>
|
||||
<string name="connect_timeout">Time-out verbinding in seconden (optie)</string>
|
||||
<string name="enter_sftp_login_title">SFTP logingegevens invoeren:</string>
|
||||
<string name="sftp_auth_mode">Authenticatiemodus</string>
|
||||
<string name="send_public_key">Zend publieke sleutel...</string>
|
||||
<string name="select_private_keyfile">Kies privé sleutel...</string>
|
||||
<string name="hint_sftp_key_name">Nieuwe sleutelnaam</string>
|
||||
<string name="hint_sftp_key_content">Nieuwe sftp-sleutel inhoud</string>
|
||||
<string name="private_key_saved">Privésleutel opgeslagen</string>
|
||||
<string name="private_key_save_failed">GEEN privé-sleutel opgeslagen: %1$s</string>
|
||||
<string name="private_key_info">Sleutelnaam en inhoud voor opslag invoeren</string>
|
||||
<string name="private_key_delete">Privé sleutel verwijderd: %1$s</string>
|
||||
<string name="private_key_delete_failed">GEEN privé-sleutel opgeslagen: %1$s</string>
|
||||
<string name="save_key">Sla persoonlijke sleutel op</string>
|
||||
<string name="delete_key">Wis privésleutel</string>
|
||||
<string name="private_key_select">Kies privésleutel</string>
|
||||
<string name="private_key_create_new">[]Voeg nieuwe toe]</string>
|
||||
<string name="hint_sftp_key_passphrase">Wachtwoordzin voor sleutel (optie)</string>
|
||||
<string name="sftp_kex_title">Sleuteluitwisseling (KEX) algoritme(n) (optie)</string>
|
||||
<string name="hint_sftp_kex">Komma-gescheiden (CSV)namen/spec</string>
|
||||
<string name="sftp_shk_title">Server hostsleutel algoritme(n) (optie)</string>
|
||||
<string name="hint_sftp_shk">Komma-gescheiden (CSV)namen/spec</string>
|
||||
<string name="enter_ftp_login_title">SFTP logingegevens invoeren:</string>
|
||||
<string name="enter_mega_login_title">Voer je MEGA account login gegevens in:</string>
|
||||
<string name="select_storage_type">Selecteer het opslagtype:</string>
|
||||
@@ -521,7 +549,9 @@
|
||||
<string name="filestoragename_gdrive">Google Drive</string>
|
||||
<string name="filestoragename_gdriveKP2A">Google Drive (KP2A bestanden)</string>
|
||||
<string name="filestoragehelp_gdriveKP2A">Als je KP2A geen toegang wilt geven tot je volledige Google Drive, kunt je deze optie selecteren. Merk op dat je eerst een databasebestand moet aanmaken, bestaande bestanden zijn niet zichtbaar voor de app. Kies deze optie uit het database scherm aanmaken, of als je al een database hebt geopend door de database te exporteren die voor deze optie wordt gekozen.</string>
|
||||
<string name="filestoragename_pcloud">PCloud (KP2A map)</string>
|
||||
<string name="filestoragehelp_pcloud">Dit opslagtype zal alleen toegang vragen tot de pCloud map \"Applications/Keepass2Android\". Als je een bestaande database uit jouw PCloud account wil gebruiken, zorg dan dat het bestand in die pCloud map wordt geplaatst.</string>
|
||||
<string name="filestoragename_pcloudall">PCloud (Full access)</string>
|
||||
<string name="filestoragename_onedrive">OneDrive</string>
|
||||
<string name="filestoragename_onedrive2">OneDrive</string>
|
||||
<string name="filestoragename_onedrive2_full">Alle bestanden en gedeelde bestanden</string>
|
||||
@@ -530,13 +560,13 @@
|
||||
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
|
||||
<string name="filestoragename_mega">MEGA</string>
|
||||
<string name="filestoragehelp_mega">Let op: Keepass2Android moet de lijst van alle bestanden in jouw Mega account downloaden om goed te werken. Om deze reden kan het benaderen van accounts met veel bestanden traag zijn.</string>
|
||||
<string name="filestoragename_content">Systeem bestand kiezer</string>
|
||||
<string name="filestoragename_content">Systeem bestandskiezer</string>
|
||||
<string name="filestorage_setup_title">Bestandstoegang initaliseren</string>
|
||||
<string name="database_location">Database locatie</string>
|
||||
<string name="help_database_location">Je kunt jouw database lokaal op je Android toestel of in de cloud opslaan (alleen de niet-Offline versie). Keepass2Android maakt de database beschikbaar, zelfs als je offline bent. Omdat de database veilig is versleuteld met AES 256 bit encryptie, kan niemand toegang krijgen tot jouw wachtwoorden behalve jij. We adviseren Dropbox te kiezen: het is beschikbaar op al je apparaten en voorziet zelfs in back-ups van vorige bestandsversies.</string>
|
||||
<string name="hint_database_location">Selecteer waar je de database wilt opslaan:</string>
|
||||
<string name="button_change_location">Locatie wijzigen</string>
|
||||
<string name="help_quickunlock">Wanneer ingeschakeld zal Keepass2Android in de achtergrond blijven draaien, zelfs wanneer de database vergrendeld is. Hierdoor kan de database later met slechts een klein gedeelte van het hoofdwachtwoord worden ontgrendeld.</string>
|
||||
<string name="help_quickunlock">Bij inschakelen blijft Keepass2Android op de achtergrond draaien, ook al is de database vergrendeld. Hierdoor kan de database op een later tijdstip worden ontgrendeld met slechts een kort deel van het hoofdwachtwoord.</string>
|
||||
<string name="master_password">Hoofdwachtwoord</string>
|
||||
<string name="help_master_password">De database is versleuteld met het hier ingevoerde wachtwoord. Kies een sterk wachtwoord om de database te beveiligen! Tip: Bedenk een zin of twee en gebruik de eerste letters van de woorden als wachtwoord. Gebruik ook de leestekens.</string>
|
||||
<string name="hint_master_password">Kies een hoofdwachtwoord om jouw database te beschermen:</string>
|
||||
@@ -546,7 +576,7 @@
|
||||
<string name="use_key_file">Gebruik sleutelbestand</string>
|
||||
<string name="error_adding_keyfile">Fout tijdens het toevoegen van het sleutelbestand!</string>
|
||||
<string name="init_otp">Laad OTP hulpbestand…</string>
|
||||
<string name="otp_explanation">Voer de volgende One-time-passwords (OTPs) in. Veeg je Yubikey NEO langs de achterkant van het apparaat om via NFC in te voeren (Yubiclip app vereist).</string>
|
||||
<string name="otp_explanation">Voer de volgende One-time-passwords (OTPs) in. Veeg je Yubikey NEO langs de achterkant van het apparaat om via NFC in te voeren (vereist Yubiclip).</string>
|
||||
<string name="otp_hint">OTP %1$d</string>
|
||||
<string name="CouldntLoadOtpAuxFile">Kan het OTP hulpbestand niet laden!</string>
|
||||
<string name="CouldntLoadOtpAuxFile_Hint">Gebruik de OtpKeyProv plugin in KeePass 2.x (PC) om jouw database in te stellen voor gebruik met OTPs!</string>
|
||||
@@ -567,12 +597,14 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">Gebruik de KeeChallenge plugin in KeePass 2.x (PC) om de database in te stellen voor gebruik met challenge/response!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">Fout bijwerken OTP hulpbestand!</string>
|
||||
<string name="TrayTotp_SeedField_title">Veldnaam van TOTP-bron</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">Wanneer je met Keepass 2 (PC) de plugin \"TrayTotp\" met afwijkende instellingen gebruikt, geef dan hier de naam van de willekeurige bron.</string>
|
||||
<string name="TrayTotp_SettingsField_title">Veldnaam TOTP-instellingen</string>
|
||||
<string name="TrayTotp_SettingsField_summary">Geef de veldnaam van het instellingenveld van TrayTotp.</string>
|
||||
<string name="TrayTotp_prefs">TrayTotp</string>
|
||||
<string name="DebugLog_prefs_prefs">Logboekbestand voor foutopsporing</string>
|
||||
<string name="DebugLog_title">Gebruik logboekbestand</string>
|
||||
<string name="FtpDebug_title">FTP/SFTP debug logging</string>
|
||||
<string name="DebugLog_summary">App uitvoer naar een lokaal logboekbestand schrijven</string>
|
||||
<string name="DebugLog_send">Logboekbestand voor foutopsporing opsturen...</string>
|
||||
<string name="loading">Laden…</string>
|
||||
@@ -593,9 +625,9 @@
|
||||
<string name="SCOPE_CURRENT_ENTRY_title">Gegevens huidige item</string>
|
||||
<string name="SCOPE_CURRENT_ENTRY_explanation">De plug-in zal alle data van het huidige database item krijgen en kan acties aanbieden en de weergave van het item wijzigen.</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE_title">Zoek eigen inloggegevens</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE_explanation">De plug-in wordt toegestaan om te zoeken naar de inloggegevens die gekoppeld zijn met zijn eigen applicatie.</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE_explanation">De plugin mag de logingegevens opvragen die zijn gekoppeld aan zijn eigen app-pakket.</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_title">Zoek inloggegevens</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_explanation">De plug-in zal worden toegestaan te zoeken naar inloggegevens voor specifieke websites of programma\'s.</string>
|
||||
<string name="SCOPE_QUERY_CREDENTIALS_explanation">De plugin mag inloggegevens opvragen voor bewuste websites of apps.</string>
|
||||
<string name="get_regular_version">Verkrijg meer opslagmethodes</string>
|
||||
<string name="CertificateWarning">Waarschuwing: Server certificaat validatie mislukt: %1$s. Installeer een passend root-certificaat op je apparaat of zie instellingen!</string>
|
||||
<string name="CertificateFailure">Fout: Server certificaat validatie mislukt! Installeer een passend root-certificaat op je apparaat of zie instellingen!</string>
|
||||
@@ -641,6 +673,24 @@
|
||||
<string name="Continue">Ga verder</string>
|
||||
<string name="NoFilenameWarning">De URI die je hebt ingevoerd lijkt niet in een bestandsnaam. Weet je zeker dat dit een geldig bestand is?</string>
|
||||
<string name="FirstInvalidCompositeKeyError">Ongeldige sleutelcombinatie! Probeer het opnieuw.</string>
|
||||
<string name="RepeatedInvalidCompositeKeyHelp"> Ongeldige samengestelde sleutel! Probeer de volgende stappen om uw database te ontgrendelen:\n
|
||||
|
||||
• Controleer of het juiste wachtwoord is ingevuld. Gebruik het oogsymbool om het ingevoerde wachtwoord te onthullen.\n
|
||||
• Controleer of het juiste wachtwoordtype is gebruikt. Let erop dat dit overeenkomt met het type dat is gekozen bij het aanmaken van de database.\n
|
||||
• Controleer of de juiste database is gekozen.
|
||||
</string>
|
||||
<string name="HintLocalBackupInvalidCompositeKey">Tip: Als de database mogelijk corrupt is of na het wijzigen de hoofdsleutel niet meer bekend is, kunt u het proberen met de laatst geopende versie van het bestand door op \"%1$s\" te tikken en de lokale back-up te selecteren.</string>
|
||||
<string name="HintLocalBackupOtherError"> \n
|
||||
• Tip: Keepass2Android heeft de laatst succesvol geopende bestandsversie opgeslagen op de interne opslag. U kunt deze openen door op \"%1$s\" te tikken en de lokale back-up te selecteren.
|
||||
</string>
|
||||
<string name="CorruptDatabaseHelp"> Bestand is beschadigd. \n
|
||||
Hier zijn enkele tips die kunnen helpen bij het opsporen van het probleem:\n
|
||||
|
||||
• Als het bestand via USB (MTP-modus) is gekopieerd, probeer het dan opnieuw met een programma zoals MyPhoneExplorer. MTP kort bestanden in bepaalde gevallen in.\n
|
||||
• Als het bestand niet vanaf dezelfde locatie op je pc kan worden geopend, is het waarschijnlijk beschadigd. Gebruik dan een database back-up. Als je vermoedt dat Keepass2Android het bestand heeft beschadigd, raadpleeg dan het ondersteuningsteam.\n
|
||||
• Kunt u het bestand nog steeds openen op uw pc, neem dan contact op met het ondersteuningsteam. U kunt proberen het bestand op te slaan met andere instellingen ( bijv. uitgepakt) op de pc en opnieuw proberen te openen in Keepass2Android.
|
||||
|
||||
</string>
|
||||
<string name="open_other_db">Een andere database openen…</string>
|
||||
<string name="select_database">Selecteer database</string>
|
||||
<string name="configure_child_dbs">Kind-databases configureren…</string>
|
||||
@@ -662,12 +712,19 @@
|
||||
<string name="remove_history">Deze versie verwijderen</string>
|
||||
<string name="DbUnlockedChannel_name">Database geopend</string>
|
||||
<string name="DbUnlockedChannel_desc">Melding bij het openen van de database</string>
|
||||
<string name="DbQuicklockedChannel_name">Snel Openen</string>
|
||||
<string name="DbQuicklockedChannel_desc">Meldingen over het openen van de database met Snel Openen</string>
|
||||
<string name="DbQuicklockedChannel_name">SnelOpenen</string>
|
||||
<string name="DbQuicklockedChannel_desc">Melding over vergrendeling van de database met Snelopenen</string>
|
||||
<string name="EntryChannel_name">Item meldingen</string>
|
||||
<string name="EntryChannel_desc">Melding voor vereenvoudigde toegang van het nu geselecteerde item.</string>
|
||||
<string name="CloseDbAfterFailedAttempts">Sluit de database na drie mislukte biometrische ontgrendelpogingen.</string>
|
||||
<string name="WarnFingerprintInvalidated">Waarschuwing! Biometrische authenticatie wordt uitgeschakeld door Android, bijv. na het toevoegen van een nieuwe vingerafdruk in de instellingen van jouw apparaat. Zorg ervoor dat je de database altijd kunt ontgrendelen met het hoofdwachtwoord!</string>
|
||||
<string-array name="ChangeLog_1_10">
|
||||
<item>Machtiging voor meldingen op Android 13+ toevoegen</item>
|
||||
<item>De FTP en SFTP implementatie verbeteren</item>
|
||||
<item>Toegang toevoegen tot volledige pCloud</item>
|
||||
<item>Systeemtaal laten kiezen in het taalvenster</item>
|
||||
<item>Probleem met onthouden van type sleutelbestand + wachtwoord oplossen</item>
|
||||
</string-array>
|
||||
<string-array name="ChangeLog_1_09e">
|
||||
<item>Bug fix op crashes en onverwachte log-outs</item>
|
||||
<item>Schakel over naar nieuwe SFTP-implementatie ter ondersteuning van moderne publieke sleutel algoritmen zoals rsa-sha2-256</item>
|
||||
@@ -686,7 +743,7 @@
|
||||
<item>Repareer de automatische invulprompt in Firefox</item>
|
||||
<item>Integreer suggesties met toetsenbord (met Android 11+)</item>
|
||||
<item>Toestaan om de app taal te wijzigen in de instellingen</item>
|
||||
<item>Optie toevoegen om database te synchroniseren na Snel Openen</item>
|
||||
<item>Optie toevoegen om database te synchroniseren na SnelOpenen</item>
|
||||
<item>Bug fix: Maak geen kleine bestandsnamen bij het opslaan naar Dropbox</item>
|
||||
</string-array>
|
||||
<string-array name="ChangeLog_1_09a">
|
||||
@@ -696,7 +753,7 @@
|
||||
<item>Verbeteringen van Autofill (pop-up werd niet weergegeven in Chrome, betere subdomein ondersteuning)</item>
|
||||
<item>Verbeteringen in de OneDrive implementatie: grootte limiet verwijderd, geen overbodige authenticatieverzoeken meer</item>
|
||||
<item>Optie toegevoegd om licht/donker ontwerp te selecteren uit systeeminstellingen inclusief nachtplannen, vereist Android 10+</item>
|
||||
<item>Update de Dropbox-implementatie om de nieuwe verificatiemethode te ondersteunen.</item>
|
||||
<item>Update de Dropbox-implementatie om de nieuwe authenticatiemethode te ondersteunen.</item>
|
||||
<item>Nieuw ingestelde vingerafdrukontgrendeling wordt ongeldig na het toevoegen van een vingerafdruk in systeeminstellingen voor meer veiligheid.</item>
|
||||
<item>Toestaan om bestanden te openen via de systeem bestandskiezer, waarbij de alleen-lezen vlag genegeerd wordt</item>
|
||||
<item>Sta toe om items te verplaatsen vanuit het item weergave menu</item>
|
||||
@@ -713,7 +770,7 @@
|
||||
</string-array>
|
||||
<string-array name="ChangeLog_1_08c">
|
||||
<item>Pakketnamen van Android-apps worden niet meer opgeslagen in het URL-veld</item>
|
||||
<item>Vergrendelgedrag verbeterd - biometrische prompt wordt niet langer weergeven direct na ontgrendelen</item>
|
||||
<item>Verbeterde vergrendeling - niet langer biometrische prompt direct na ontgrendeling</item>
|
||||
<item>OkHttp bijgewerkt om HTTP/2 te ondersteunen</item>
|
||||
<item>Ontbrekende vertaling(en) verbeterd</item>
|
||||
</string-array>
|
||||
@@ -733,6 +790,103 @@
|
||||
<item>Bugs opgelost</item>
|
||||
<item>Bugs opgelost</item>
|
||||
</string-array>
|
||||
<string name="ChangeLog_1_07b"> Versie 1.07b\n
|
||||
* Verbeter de prestaties van Argon2 door de oorspronkelijke implementatie te gebruiken (Met dank aan Chih-Hsuan Yen!)\n
|
||||
* Toestaan om vingerafdruk uit te schakelen door op het vingerafdrukpictogram te klikken (voorkomt probleem met vingerafdruklezers onder het scherm, met dank aan marcoDallas!)\n
|
||||
* Herstel cursorpositie bij het wisselen van de zichtbaarheid van het wachtwoord (met dank aan DDoSolitary!)\n
|
||||
* Verbeteringen van de pCloud-implementatie (met weer dank aan gilbsgilbs!)\n
|
||||
* Automatisch invullen ondersteunen voor meer browsers\n
|
||||
* Nieuwe implementatie voor OneDrive: Ondersteuning voor OneDrive for Business, gedeelde bestanden, selecteerbare toegangsbereiken, meerdere accounts en oplossing voor problemen met offline toegang.\n
|
||||
* Fout oplossingen
|
||||
</string>
|
||||
<string name="ChangeLog_1_07"> Versie 1.07\n
|
||||
* Oplossing voor crashes op Samsung\'s Android 9\n
|
||||
* Je kunt nu meer dan 1 database openen, compatibel met KeeAutoExec\n
|
||||
* SFTP: public key authenticatie, controle op verandering van server sleutel\n
|
||||
* Introductie van pCloud ondersteuning - dank aan gilbsgilbs!\n
|
||||
* NextCloud ondersteuning expliciet gemaakt\n
|
||||
* Opslaan en bijwerken van invoerbijlagen verbeteren\n
|
||||
* Meer opties voor het aanpassen van app gedrag in persoonlijke voorkeuren\n
|
||||
* SSL: vertrouw gebruiker certicaten\n
|
||||
* Automatisch invullen verbeterd (werkt nu met Firefox, minder popups)\n
|
||||
* Fout oplossingen\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_06"> Versie 1.06\n
|
||||
* Gebruik van ykDroid in plaats van YubiChallenge als app voor Yubikey challenge/response.\n
|
||||
* Ondersteuning voor KeepassXC-stijl challenge/response. Let op: de database-indeling moet KDBX4 zijn!\n
|
||||
* Weiger verwijderde bestanden te laden van Google Drive\n
|
||||
* Andere TLS implementatie voor FTPS, om een JSch bug heen gewerkt voor servers die gssapi-with-mic ondersteunen\n
|
||||
* problemen opgelost\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_05"> Versie 1.05\n
|
||||
* Gebruik melding kanalen op Android 8 met configuratie via systeem instellingen\n
|
||||
* Toon pictogram in melding\n
|
||||
* Gebruik adaptieve pictogrammen voor Android 8, gebruik rond launcherpictogram voor Android 7\n
|
||||
* Optie om direct te zoeken na openen (see instellingen)\n
|
||||
* De manier waarop bestanden worden geschreven via Storage Access Framework is veranderd, dit lost problemen op met het schrijven van bestanden op Google Drive die geopend waren via de Systeem bestandsbeheerder\n
|
||||
* Informatieteksten toegevoegd om vaak voorkomende misverstanden te voorkomen\n
|
||||
* Maak lokaal een back-up van correct geopende databases om kans op dataverlies te verkleinen\n
|
||||
* JSch bijgewerkt om recentere SSH ciphers te ondersteunen\n
|
||||
* Mogelijk gemaakt om verbindingsinstellingen te wijzigen, bijvoorbeeld als het WebDav wachtwoord veranderde\n
|
||||
* Ondersteuning voor Yubikey Neo\'s static password mode toegevoegd\n
|
||||
* Automatisch invullen suggestie kan uitgezet worden\n
|
||||
* Data lek naar logcat opgelost\n
|
||||
* Diverse bugs opgelost\n
|
||||
|
||||
|
||||
ChangeLog_1_05 </string>
|
||||
<string name="ChangeLog_1_04b">Versie 1.04b\n
|
||||
* Voorkom vastlopen bij automatisch invullen op Huawei apparaten.\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_04">Versie 1.04\n
|
||||
* Automatisch invullen toegevoegd voor Android 8.0 en hoger.\n
|
||||
* Bibliotheken, gereedschap en SDK-versie bijgewerkt.\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_03">Versie 1.03\n
|
||||
* Toegankelijkheid service voor automatisch invullen verwijderd zoals gevraagd door Google. Raadpleeg de wachtwoord toegangsinstellingen om een plugin te vinden die de vorige functionaliteit biedt.\n
|
||||
* Derde partij apps weer toegevoegd als opslag optie\n
|
||||
* Geïntegreerde afbeeldingsweergave van gekoppelde beelden zonder deze over te dragen aan andere apps\n
|
||||
* OkHttp opgewaardeerd om problemen op te lossen met sommige verbindingen\n
|
||||
* Steun voor KeeTrayTOTP items, ondersteund nu Steam items\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_02">Versie 1.02\n
|
||||
* Verschillende beveiligingsverbeteringen. Dank gaat uit naar jean-baptiste.cayrou@thalesgroup.com en vincent.fargues@thalesgroup.com voor hun veiligheidsrapport en samenwerking!\n
|
||||
* Ondersteuning voor KeyboardSwapPlugin (zie verder wachtwoord toegang opties): staat automatisch wisselen van een input methode toe op non-rooted apparaten. Met dank aan Mishaal Rahman van XDA-Developers die dit mogelijk maakte.\n
|
||||
* Fix voor toegankelijkheids service met recente Chrome versies.\n
|
||||
* Fix om onnodig wissen van de vingerafdrukdata te voorkomen\n
|
||||
* Fix voor onbelangrijke chrashes\n
|
||||
* Dropbox SDK bijgewerkt om compabiliteit in de toekomst te garanderen\n
|
||||
* Fout rapporten van Xamarin Insights verwijderd\n
|
||||
* Ontwikkeltools geupdated\n </string>
|
||||
<string name="ChangeLog_1_01g"> Versie 1.01-g\n
|
||||
* Oplossing voor een crash tijdens offline werken\n
|
||||
* Oplossing voor onjuiste codering van FTP(S) inloggegevens\n
|
||||
* Oplossing voor crashes bij het gebruik van OneDrive op oudere Android versies\n
|
||||
* Tijden weergegeven als lokale tijd in beginscherm\n
|
||||
</string>
|
||||
<string name="ChangeLog_1_01"> Versie 1.01\n
|
||||
* * ondersteuning toegevoegd voor het nieuwe KDBX-4-formaat (compatibel met Keepass 2.35) inclusief Argon2-sleutelafleiding en ChaCha20-codering.\n
|
||||
* WebDav bestandsopslag opnieuw geïmplementeerd, maakt nu bladeren door bestanden mogelijk en ondersteunt moderne codering.\n
|
||||
* Opnieuw geïmplementeerde FTP bestandsopslag, maakt nu bladeren door bestanden mogelijk en ondersteunt versleuteling (FTPS).\n
|
||||
* Bijgewerkt naar OneDrive SDK (eerder gebruikte Live SDK is niet langer bijgewerkt)\n
|
||||
* Bijgewerkt naar Dropbox SDK versie 2 (eerder gebruikte versie 1 SDK is verouderd).\n
|
||||
* Ondersteuning toegevoegd voor OwnCloud.\n
|
||||
* Vragen om opslagtoestemming voordat lokale bestanden worden geopend
|
||||
</string>
|
||||
<string name="ChangeLog_0_9_9"> Versie 0.9.9\n
|
||||
* Volledig herontwerp van de UI. Met veel dank aan Stefano Pignataro (http://www.spstudio.at) for his support!\n
|
||||
* Aangepaste pictogrammen toestaan\n
|
||||
* Ondersteuning voor de Multi Window-modus op Samsung-apparaten\n
|
||||
* Verhoogd standaard aantal coderingsronden voor nieuwe databases\n
|
||||
* Controleer op dubbele sleutels van extra velden om gegevensverlies te voorkomen\n
|
||||
</string>
|
||||
<string name="ChangeLog_0_9_8"> Versie 0.9.8\n
|
||||
* Ondersteuning voor Storage Access Framework (maakt schrijven naar SD-kaart en Google Drive mogelijk in KP2A Offline)\n
|
||||
* Probeer foutieve gebruikersinvoer te detecteren bij het invoeren van WebDAV URL\'s (map in plaats van bestand)\n
|
||||
* Wachtwoordlettertype gewijzigd\n
|
||||
* Het wijzigen van Dropbox-account toestaan\n
|
||||
* Fout verholpen: Onthoudt nu OTP-wachtwoord
|
||||
</string>
|
||||
<string name="ChangeLog_keptDonate">Uitgelezen kans om biertje te schenken of iets anders</string>
|
||||
<string-array name="clipboard_timeout_options">
|
||||
<item>30 seconden</item>
|
||||
@@ -782,8 +936,8 @@
|
||||
</string-array>
|
||||
<string-array name="sftp_auth_modes">
|
||||
<item>Wachtwoord</item>
|
||||
<item>KP2A Private/Public key</item>
|
||||
<item>Custom Private key</item>
|
||||
<item>KP2A privé/publieke sleutel</item>
|
||||
<item>Aangepaste privésleutel</item>
|
||||
</string-array>
|
||||
<string-array name="AcceptAllServerCertificates_options">
|
||||
<item>Negeer mislukte certificaat validaties</item>
|
||||
@@ -801,11 +955,16 @@
|
||||
<string name="autofill_enable_for">Automatisch invullen inschakelen voor %1$s</string>
|
||||
<string name="invalid_link_association">Kon domein %1$s niet koppelen met app %2$s</string>
|
||||
<string name="enable_fingerprint_hint">Keepass2Android heeft biometrische hardware gedetecteerd. Wil je Biometrische ontgrendeling voor deze database inschakelen?</string>
|
||||
<string name="post_notifications_dialog_title">Meldingen toestaan</string>
|
||||
<string name="post_notifications_dialog_message">Keepass2Android kan meldingen weergeven met knoppen om waarden zoals wachtwoorden en TOTP\'s naar het klembord te kopiëren, of om het ingebouwde toetsenbord op te roepen. Dit is handig om waarden over te brengen naar andere apps zonder herhaaldelijk naar Keepass2Android over te schakelen. Wilt u dergelijke meldingen inschakelen?</string>
|
||||
<string name="post_notifications_dialog_allow">Meldingen toestaan</string>
|
||||
<string name="post_notifications_dialog_disable">Schakel deze functie uit</string>
|
||||
<string name="post_notifications_dialog_notnow">Niet nu</string>
|
||||
<string name="understand">Ik begrijp het</string>
|
||||
<string name="dont_show_again">Niet meer tonen</string>
|
||||
<string name="masterkey_infotext_head">Weet je het hoofdwachtwoord nog?</string>
|
||||
<string name="masterkey_infotext_main">Merk op dat zonder hoofdwachtwoord de database niet te openen is. Er is geen manier om het hoofdwachtwoord te \"resetten\".</string>
|
||||
<string name="masterkey_infotext_fingerprint_note">Houd er ook rekening mee dat Biometrische ontgrendeling werkt door de hoofdsleutel op te slaan in de veilige opslag van Android. Deze opslag kan op elk moment door Android worden verwijderd, bijvoorbeeld wanneer je een nieuwe vingerafdruk toevoegt in de systeeminstellingen. Vertrouw dus niet op Biometrische ontgrendeling maar onthoud a.u.b. je hoofdwachtwoord!</string>
|
||||
<string name="masterkey_infotext_fingerprint_note">Houd er ook rekening mee dat biometrische ontgrendeling werkt door opslaan van de hoofdsleutel in de beveiligde opslag van Android. Deze opslag kan op elk moment door Android worden verwijderd, bijvoorbeeld als je een nieuwe vingerafdruk toevoegt in de systeeminstellingen. Vertrouw dus niet op biometrische ontgrendeling, maar onthoud je hoofdwachtwoord!</string>
|
||||
<string name="backup_infotext_head">Worden er back-ups gemaakt van jouw database?</string>
|
||||
<string name="backup_infotext_main">Keepass2Android bewaart je wachtwoorden in een file op een door jou gekozen locatie. Weet je zeker dat je deze file nog steeds hebt als je telefoon verloren raakt, of gestolen, of als de file gewist wordt? Zorg alsjeblieft altijd voor een recente back-up op een veilige plaats!</string>
|
||||
<string name="backup_infotext_note">Om nu een back-up te maken, ga naar %1$s > %2$s > %3$s.</string>
|
||||
|
@@ -404,6 +404,14 @@
|
||||
<string name="ShowSeparateNotifications_summary">Exibir notificações separadas para copiar nome de usuário e senha para área de transferência e ativar o teclado.</string>
|
||||
<string name="AccServiceAutoFill_prefs">Serviço de Acessibilidade para Autopreenchimento</string>
|
||||
<string name="AutoFill_prefs">Serviço de Autopreenchimento</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">Ao preencher automaticamente uma entrada com TOTP, mostre a notificação de entrada com um botão Copiar TOTP</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">Mostrar notificação da entrada</string>
|
||||
<string name="AutoFillTotp_prefs_title">Preenchimento automático para entradas TOTP</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">Copiar TOTP para a área de transferência</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">Ao preencher automaticamente uma entrada com TOTP, copie o TOTP para a área de transferência</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">Ao preencher automaticamente uma entrada com TOTP, ative o teclado integrado. O teclado possui um botão TOTP.</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">Ativar teclado integrado</string>
|
||||
<string name="TotpCopiedToClipboard">Copiado TOTP para a área de transferência</string>
|
||||
<string name="ShowKp2aKeyboardNotification_title">Notificação do teclado KP2A</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Tornar toda a entrada disponível através do teclado KP2A (recomendado).</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">Trocar teclado</string>
|
||||
@@ -591,6 +599,7 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">Por favor, use o plugin KeeChallenge no KeePass 2.x (PC) para configurar seu banco de dados para uso com desafio-resposta!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">Erro ao atualizar o arquivo OTP auxiliar!</string>
|
||||
<string name="TrayTotp_SeedField_title">Nome do campo da semente TOTP</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">Se você estiver usando o plugin Keepass 2 \"TrayTotp\" com configurações não-padrão, digite o nome do campo para o campo de semente aqui de acordo com as configurações no PC.</string>
|
||||
<string name="TrayTotp_SettingsField_title">TOTP configurações nome do campo</string>
|
||||
<string name="TrayTotp_SettingsField_summary">Digite o nome do campo do campo de configurações para TrayTotp aqui.</string>
|
||||
@@ -944,6 +953,16 @@
|
||||
* recarrega automaticamente o banco de dados quando uma alteração é detectada, resolve problemas de segurança relacionados à revelação da senha mestra\n
|
||||
* layout de teclado pequeno aprimorado e tema de configurações de teclado fixo (graças a Wiktor Ławski)\n
|
||||
</string>
|
||||
<string name="ChangeLog_0_9_5"> <b>Versão 0.9.5</b>\n
|
||||
* Corrigidos problemas com a navegação de arquivos (especialmente no Android 4.4)\\n
|
||||
* Corrigido problema ao carregar arquivos .kdb (Keepass 1) no Nexus 5 com Android Lollipop\\n
|
||||
* Adicionada opção para evitar capturas de tela/exibição de aplicativos na lista de aplicativos recentes\\n
|
||||
* Corrigido problema com armazenamento de arquivos do Google Drive (edição regular)\\n
|
||||
* Permitir arquivos importantes em tipos de armazenamento deliberados (edição regular)\\n
|
||||
* SDK do Dropbox atualizado para incluir um patch de segurança oficial (edição regular)\\n
|
||||
* Ferramentas de compilação atualizadas --> tamanho do apk aumentado :-(\n
|
||||
Eu prometi mais algumas mudanças. Eles virão no próximo lançamento - desculpe. Eu queria publicar esses hot fixes o mais rápido possível.
|
||||
</string>
|
||||
<string name="ChangeLog_keptDonate">Estendida a possibilidade de doar uma cerveja ou outra coisa</string>
|
||||
<string-array name="clipboard_timeout_options">
|
||||
<item>30 segundos</item>
|
||||
|
@@ -402,6 +402,14 @@
|
||||
<string name="ShowSeparateNotifications_summary">Prikaži ločena obvestila za kopiranje uporabniškega imena in gesla na odložišče in omogočanje tipkovnice.</string>
|
||||
<string name="AccServiceAutoFill_prefs">Storitev za samodejno izpolnjevanje</string>
|
||||
<string name="AutoFill_prefs">Storitev samodejnega izpolnjevanja</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">Pri samodejnem izpolnjevanju vnosa s TOTP prikažite obvestilo o vnosu z gumbom Kopiraj TOTP</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">Prikaži obvestilo o vstopu</string>
|
||||
<string name="AutoFillTotp_prefs_title">Samodejno izpolnjevanje vnosov TOTP</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">Kopiraj TOTP v odložišče</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">Pri samodejnem izpolnjevanju vnosa s TOTP kopirajte TOTP v odložišče</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">Pri samodejnem izpolnjevanju vnosa s TOTP aktivirajte vgrajeno tipkovnico. Tipkovnica ima gumb TOTP.</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">Aktivirajte vgrajeno tipkovnico</string>
|
||||
<string name="TotpCopiedToClipboard">TOTP kopiran v odložišče</string>
|
||||
<string name="ShowKp2aKeyboardNotification_title">Obvestilo tipkovnice KP2A</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Naredi poln vnos dostopen preko tipkovnice KP2A (priporočljivo).</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">Preklopi tipkovnico</string>
|
||||
@@ -589,6 +597,7 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">Uporabite vtičnik KeeChallenge v KeePassu 2.x (PC), da nastavite svojo podatkovno zbirko za uporabo z odgovorom izziva!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">Napaka pri posodabljanju pomožne datoteke OTP!</string>
|
||||
<string name="TrayTotp_SeedField_title">Ime polja semena TOTP</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">Če uporabljate vtičnik KeePassa 2 \"TrayTotp\" s samo privzetimi nastavitvami, tu vnesite ime polja semena glede na nastavitve na računalniku.</string>
|
||||
<string name="TrayTotp_SettingsField_title">Ime polja nastavitev TOTP</string>
|
||||
<string name="TrayTotp_SettingsField_summary">Tu vnesite ime polja nastavitev za TrayTotp.</string>
|
||||
|
@@ -402,6 +402,14 @@
|
||||
<string name="ShowSeparateNotifications_summary">为复制账户信息和激活键盘分别显示通知</string>
|
||||
<string name="AccServiceAutoFill_prefs">自动填充服务(辅助功能)</string>
|
||||
<string name="AutoFill_prefs">自动填充服务</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">当用TOTP自动填充条目时,显示带“复制TOTP”按钮的条目通知</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">显示条目通知</string>
|
||||
<string name="AutoFillTotp_prefs_title">自动填充TOTP条目</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">复制TOTP到剪贴板</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">当使用TOTP自动填充条目时,复制TOTP到剪贴板</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">当用TOTP自动填充条目时,激活内置键盘。键盘有一个TOTP按钮。</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">激活内置键盘</string>
|
||||
<string name="TotpCopiedToClipboard">已复制TOTP到剪贴板</string>
|
||||
<string name="ShowKp2aKeyboardNotification_title">KP2A 键盘通知</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">使整个条目可通过 KP2A 键盘获取(推荐)。</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">切换键盘</string>
|
||||
@@ -589,6 +597,7 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">请在 KeePass 2.x (PC) 中使用 KeeChallenge 插件,以使用挑战—响应配置您的数据库!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">更新一次性密码辅助文件时出错 !</string>
|
||||
<string name="TrayTotp_SeedField_title">一次性密码种子字段名称</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">如果您在使用 Keepass 2 插件 \"TrayTotp\" 为非默认设置,在电脑上输入设置种子字段的字段名称。</string>
|
||||
<string name="TrayTotp_SettingsField_title">TOTP 字段名称设置</string>
|
||||
<string name="TrayTotp_SettingsField_summary">在这里输入设置字段的字段名称 TrayTotp</string>
|
||||
|
@@ -47,6 +47,7 @@
|
||||
<string name="oi_filemanager_web">https://openintents.googlecode.com/files/FileManager-2.0.2.apk</string>
|
||||
<string name="permission_desc2">KP2A Search</string>
|
||||
<string name="permission_desc3">KP2A Choose autofill dataset</string>
|
||||
<string name="AutoFillTotp_prefs_screen_key">AutoFillTotp_prefs_screen_key</string>
|
||||
|
||||
|
||||
<!-- Preference settings -->
|
||||
|
@@ -402,6 +402,16 @@
|
||||
<string name="ShowSeparateNotifications_summary">Show separate notifications for copying username and password to clipboard and activating the keyboard.</string>
|
||||
<string name="AccServiceAutoFill_prefs">AutoFill Accessibility-Service</string>
|
||||
<string name="AutoFill_prefs">AutoFill Service</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_summary">When autofilling an entry with TOTP, show the entry notification with a Copy TOTP button</string>
|
||||
<string name="AutoFillTotp_prefs_ShowNotification_title">Show entry notification</string>
|
||||
<string name="AutoFillTotp_prefs_title">Autofill for TOTP entries</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_title">Copy TOTP to clipboard</string>
|
||||
<string name="AutoFillTotp_prefs_CopyTotpToClipboard_summary">When autofilling an entry with TOTP, copy the TOTP to the clipboard</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_summary">When autofilling an entry with TOTP, activate the built-in keyboard. The keyboard has a TOTP button.</string>
|
||||
<string name="AutoFillTotp_prefs_ActivateKeyboard_title">Activate built-in keyboard</string>
|
||||
|
||||
<string name="TotpCopiedToClipboard">Copied TOTP to clipboard</string>
|
||||
|
||||
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
|
||||
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard (recommended).</string>
|
||||
<string name="OpenKp2aKeyboardAutomatically_title">Switch keyboard</string>
|
||||
@@ -589,6 +599,7 @@
|
||||
<string name="CouldntLoadChalAuxFile_Hint">Please use the KeeChallenge plugin in KeePass 2.x (PC) to configure your database for use with challenge-response!</string>
|
||||
<string name="ErrorUpdatingChalAuxFile">Error updating OTP auxiliary file!</string>
|
||||
<string name="TrayTotp_SeedField_title">TOTP Seed field name</string>
|
||||
<string name="TOTP">TOTP</string>
|
||||
<string name="TrayTotp_SeedField_summary">If you are using the Keepass 2 plugin "TrayTotp" with non-default settings, enter the field name for the seed field here according to the settings on the PC.</string>
|
||||
<string name="TrayTotp_SettingsField_title">TOTP Settings field name</string>
|
||||
<string name="TrayTotp_SettingsField_summary">Enter the field name of the settings field for TrayTotp here.</string>
|
||||
|
@@ -461,7 +461,8 @@
|
||||
android:defaultValue="false"
|
||||
android:title="@string/LogAutofillView_title"
|
||||
android:key="@string/LogAutofillView_key" />
|
||||
|
||||
|
||||
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
@@ -476,6 +477,38 @@
|
||||
android:summary="@string/AutofillDisabledQueriesPreference_summary"
|
||||
android:persistent="false"
|
||||
android:key="AutofillDisabledQueriesPreference_key"/>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="@string/AutoFillTotp_prefs_screen_key"
|
||||
android:title="@string/AutoFillTotp_prefs_title"
|
||||
>
|
||||
<keepass2android.ToolbarPreference
|
||||
android:key="@string/AutoFillTotp_prefs_screen_key"
|
||||
android:title="@string/AutoFillTotp_prefs_title" />
|
||||
|
||||
<CheckBoxPreference android:key="AutoFillTotp_prefs_ShowNotification_key"
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/AutoFillTotp_prefs_ShowNotification_summary"
|
||||
android:defaultValue="true"
|
||||
android:title="@string/AutoFillTotp_prefs_ShowNotification_title"
|
||||
/>
|
||||
<CheckBoxPreference android:key="AutoFillTotp_prefs_CopyTotpToClipboard_key"
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/AutoFillTotp_prefs_CopyTotpToClipboard_summary"
|
||||
android:defaultValue="true"
|
||||
android:title="@string/AutoFillTotp_prefs_CopyTotpToClipboard_title"
|
||||
/>
|
||||
<CheckBoxPreference android:key="AutoFillTotp_prefs_ActivateKeyboard_key"
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/AutoFillTotp_prefs_ActivateKeyboard_summary"
|
||||
android:defaultValue="false"
|
||||
android:title="@string/AutoFillTotp_prefs_ActivateKeyboard_title"
|
||||
/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -306,7 +307,27 @@ namespace keepass2android
|
||||
}
|
||||
else if (Intent.Action == Intent.ActionSend)
|
||||
{
|
||||
AppTask = new SearchUrlTask { UrlToSearchFor = Intent.GetStringExtra(Intent.ExtraText) };
|
||||
ActivationCondition activationCondition = ActivationCondition.Never;
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||
{
|
||||
activationCondition = ActivationCondition.Always;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||
// automatically bring up the Keyboard selection dialog
|
||||
if (prefs.GetBoolean(this.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), this.Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||
{
|
||||
activationCondition = ActivationCondition.Always;
|
||||
}
|
||||
}
|
||||
|
||||
AppTask = new SearchUrlTask()
|
||||
{
|
||||
UrlToSearchFor = Intent.GetStringExtra(Intent.ExtraText),
|
||||
ActivateKeyboard = activationCondition
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -63,6 +63,12 @@ namespace keepass2android
|
||||
launchMode.Launch(act, i);
|
||||
}
|
||||
|
||||
public static void Launch(Activity act, OpenSpecificEntryTask task, ActivityLaunchMode launchMode)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(ShareUrlResults));
|
||||
task.ToIntent(i);
|
||||
launchMode.Launch(act, i);
|
||||
}
|
||||
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
@@ -76,21 +82,15 @@ namespace keepass2android
|
||||
//if user presses back to leave this activity:
|
||||
SetResult(Result.Canceled);
|
||||
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.select_other_entry, true);
|
||||
UpdateBottomBarElementVisibility(Resource.Id.add_url_entry, true);
|
||||
|
||||
|
||||
if (App.Kp2a.DatabaseIsUnlocked)
|
||||
{
|
||||
var searchUrlTask = ((SearchUrlTask)AppTask);
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
Query(searchUrl, searchUrlTask.AutoReturnFromQuery);
|
||||
Query();
|
||||
}
|
||||
// else: LockCloseListActivity.OnResume will trigger a broadcast (LockDatabase) which will cause the activity to be finished.
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override void OnSaveInstanceState(Bundle outState)
|
||||
@@ -99,12 +99,25 @@ namespace keepass2android
|
||||
AppTask.ToBundle(outState);
|
||||
}
|
||||
|
||||
private void Query(string url, bool autoReturnFromQuery)
|
||||
private void Query()
|
||||
{
|
||||
|
||||
bool canAutoReturnFromQuery = true;
|
||||
bool shouldAutoReturnFromQuery = true;
|
||||
try
|
||||
{
|
||||
Group = GetSearchResultsForUrl(url);
|
||||
if (AppTask is SearchUrlTask searchUrlTask)
|
||||
{
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
canAutoReturnFromQuery = searchUrlTask.AutoReturnFromQuery;
|
||||
shouldAutoReturnFromQuery = PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key), true);
|
||||
Group = GetSearchResultsForUrl(searchUrl);
|
||||
}
|
||||
else if (AppTask is OpenSpecificEntryTask openEntryTask)
|
||||
{
|
||||
Group = GetSearchResultsForUuid(openEntryTask.EntryUuid);
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||
@@ -114,7 +127,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
//if there is exactly one match: open the entry
|
||||
if ((Group.Entries.Count() == 1) && autoReturnFromQuery && PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key),true))
|
||||
if ((Group.Entries.Count() == 1) && canAutoReturnFromQuery && shouldAutoReturnFromQuery)
|
||||
{
|
||||
LaunchActivityForEntry(Group.Entries.Single(),0);
|
||||
return;
|
||||
@@ -131,32 +144,57 @@ namespace keepass2android
|
||||
FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group);
|
||||
|
||||
View selectOtherEntry = FindViewById (Resource.Id.select_other_entry);
|
||||
View createUrlEntry = FindViewById(Resource.Id.add_url_entry);
|
||||
|
||||
var newTask = new SearchUrlTask() {AutoReturnFromQuery = false, UrlToSearchFor = url};
|
||||
if (AppTask is SelectEntryTask currentSelectTask)
|
||||
newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications;
|
||||
|
||||
selectOtherEntry.Click += (sender, e) => {
|
||||
GroupActivity.Launch (this, newTask, new ActivityLaunchModeRequestCode(0));
|
||||
if (AppTask is OpenSpecificEntryTask)
|
||||
{
|
||||
selectOtherEntry.Visibility = ViewStates.Gone;
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
var searchUrlTask = AppTask as SearchUrlTask;
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
selectOtherEntry.Visibility = ViewStates.Visible;
|
||||
|
||||
SearchUrlTask newTask;
|
||||
if (AppTask is SelectEntryTask currentSelectTask)
|
||||
{
|
||||
newTask = new SearchUrlTask() { AutoReturnFromQuery = false, UrlToSearchFor = searchUrl, ActivateKeyboard = currentSelectTask.ActivateKeyboard };
|
||||
newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications;
|
||||
newTask.ActivateKeyboard = currentSelectTask.ActivateKeyboard;
|
||||
newTask.CopyTotpToClipboard = currentSelectTask.CopyTotpToClipboard;
|
||||
}
|
||||
else
|
||||
newTask = new SearchUrlTask() { AutoReturnFromQuery = false, UrlToSearchFor = searchUrl, ActivateKeyboard = ActivationCondition.Never };
|
||||
|
||||
|
||||
selectOtherEntry.Click += (sender, e) => {
|
||||
GroupActivity.Launch(this, newTask, new ActivityLaunchModeRequestCode(0));
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Visible;
|
||||
createUrlEntry.Click += (sender, e) =>
|
||||
{
|
||||
GroupActivity.Launch(this, new CreateEntryThenCloseTask { Url = searchUrl, ShowUserNotifications = (AppTask as SelectEntryTask)?.ShowUserNotifications ?? ActivationCondition.Always }, new ActivityLaunchModeRequestCode(0));
|
||||
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), ToastLength.Long).Show();
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
View createUrlEntry = FindViewById (Resource.Id.add_url_entry);
|
||||
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Visible;
|
||||
createUrlEntry.Click += (sender, e) =>
|
||||
{
|
||||
GroupActivity.Launch(this, new CreateEntryThenCloseTask { Url = url, ShowUserNotifications = (AppTask as SelectEntryTask)?.ShowUserNotifications ?? ShowUserNotificationsMode.Always }, new ActivityLaunchModeRequestCode(0));
|
||||
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), ToastLength.Long).Show();
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
Util.MoveBottomBarButtons(Resource.Id.select_other_entry, Resource.Id.add_url_entry, Resource.Id.bottom_bar, this);
|
||||
}
|
||||
@@ -201,6 +239,31 @@ namespace keepass2android
|
||||
return resultsGroup;
|
||||
}
|
||||
|
||||
|
||||
public static PwGroup GetSearchResultsForUuid(string uuid)
|
||||
{
|
||||
PwGroup resultsGroup = null;
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
|
||||
var resultsForThisDb = db.SearchForUuid(uuid);
|
||||
|
||||
if (resultsGroup == null)
|
||||
{
|
||||
resultsGroup = resultsForThisDb;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var entry in resultsForThisDb.Entries)
|
||||
{
|
||||
resultsGroup.AddEntry(entry, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultsGroup;
|
||||
}
|
||||
|
||||
public override bool OnSearchRequested()
|
||||
{
|
||||
Intent i = new Intent(this, typeof(SearchActivity));
|
||||
|
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using Android.Content;
|
||||
using keepass2android;
|
||||
using KeePassLib.Collections;
|
||||
|
||||
namespace PluginTOTP
|
||||
@@ -39,23 +40,34 @@ namespace PluginTOTP
|
||||
{
|
||||
TotpData res = new TotpData();
|
||||
string data;
|
||||
if (!_entryFields.TryGetValue("otp", out data))
|
||||
var otpKey = "otp";
|
||||
if (!_entryFields.TryGetValue(otpKey, out data))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
NameValueCollection parameters = ParseQueryString(data);
|
||||
res.InternalFields.Add(otpKey);
|
||||
|
||||
if (parameters[KeyParameter] == null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res.TotpSeed = parameters[KeyParameter];
|
||||
|
||||
try
|
||||
{
|
||||
res.TotpSeed = parameters[KeyParameter];
|
||||
|
||||
|
||||
res.Duration = GetIntOrDefault(parameters, StepParameter, 30).ToString();
|
||||
res.Length = GetIntOrDefault(parameters, SizeParameter, 6).ToString();
|
||||
|
||||
res.IsTotpEntry = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.Log("Cannot parse seed");
|
||||
}
|
||||
|
||||
res.Duration = GetIntOrDefault(parameters, StepParameter, 30).ToString();
|
||||
res.Length = GetIntOrDefault(parameters, SizeParameter, 6).ToString();
|
||||
|
||||
res.IsTotpEntry = true;
|
||||
return res;
|
||||
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ namespace keepass2android
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res.InternalFields.Add("otp");
|
||||
|
||||
string otpUriStart = "otpauth://totp/";
|
||||
|
||||
|
@@ -5,6 +5,7 @@ using keepass2android;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Cryptography;
|
||||
using KeePassLib.Utility;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
|
||||
namespace PluginTOTP
|
||||
{
|
||||
@@ -13,14 +14,18 @@ namespace PluginTOTP
|
||||
public TotpData GetTotpData(IDictionary<string, string> entryFields, Context ctx, bool muteWarnings)
|
||||
{
|
||||
TotpData res = new TotpData();
|
||||
byte[] pbSecret = (GetOtpSecret(entryFields, "TimeOtp-") ?? MemUtil.EmptyByteArray);
|
||||
byte[] pbSecret = (GetOtpSecret(entryFields, "TimeOtp-", out string secretFieldKey) ?? MemUtil.EmptyByteArray);
|
||||
|
||||
if (pbSecret.Length == 0)
|
||||
return res;
|
||||
|
||||
res.InternalFields.Add(secretFieldKey);
|
||||
|
||||
string strPeriod;
|
||||
uint uPeriod = 0;
|
||||
if (entryFields.TryGetValue("TimeOtp-Period", out strPeriod))
|
||||
{
|
||||
res.InternalFields.Add("TimeOtp-Period");
|
||||
uint.TryParse(strPeriod, out uPeriod);
|
||||
}
|
||||
|
||||
@@ -33,6 +38,7 @@ namespace PluginTOTP
|
||||
uint uLength = 0;
|
||||
if (entryFields.TryGetValue("TimeOtp-Length", out strLength))
|
||||
{
|
||||
res.InternalFields.Add("TimeOtp-Length");
|
||||
uint.TryParse(strLength, out uLength);
|
||||
}
|
||||
|
||||
@@ -41,6 +47,8 @@ namespace PluginTOTP
|
||||
|
||||
string strAlg;
|
||||
entryFields.TryGetValue("TimeOtp-Algorithm", out strAlg);
|
||||
if (!string.IsNullOrEmpty(strAlg))
|
||||
res.InternalFields.Add("TimeOtp-Algorithm");
|
||||
|
||||
res.HashAlgorithm = strAlg;
|
||||
res.TotpSecret = pbSecret;
|
||||
@@ -51,32 +59,37 @@ namespace PluginTOTP
|
||||
}
|
||||
|
||||
|
||||
private static byte[] GetOtpSecret(IDictionary<string, string> entryFields, string strPrefix)
|
||||
private static byte[] GetOtpSecret(IDictionary<string, string> entryFields, string strPrefix, out string secretFieldKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
string str;
|
||||
entryFields.TryGetValue(strPrefix + "Secret", out str);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
secretFieldKey = strPrefix + "Secret";
|
||||
entryFields.TryGetValue(secretFieldKey, out str);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
return StrUtil.Utf8.GetBytes(str);
|
||||
|
||||
entryFields.TryGetValue(strPrefix + "Secret-Hex", out str);
|
||||
|
||||
secretFieldKey = strPrefix + "Secret-Hex";
|
||||
entryFields.TryGetValue(secretFieldKey, out str);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
return MemUtil.HexStringToByteArray(str);
|
||||
|
||||
entryFields.TryGetValue(strPrefix + "Secret-Base32", out str);
|
||||
|
||||
secretFieldKey = strPrefix + "Secret-Base32";
|
||||
entryFields.TryGetValue(secretFieldKey, out str);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
return MemUtil.ParseBase32(str);
|
||||
return Base32.Decode(str);
|
||||
|
||||
entryFields.TryGetValue(strPrefix + "Secret-Base64", out str);
|
||||
secretFieldKey = strPrefix + "Secret-Base64";
|
||||
entryFields.TryGetValue(secretFieldKey, out str);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
return Convert.FromBase64String(str);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
|
||||
secretFieldKey = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -10,8 +10,9 @@ namespace keepass2android
|
||||
{
|
||||
class Kp2aTotp
|
||||
{
|
||||
public const string TotpKey = "TOTP";
|
||||
|
||||
readonly ITotpPluginAdapter[] _pluginAdapters = new ITotpPluginAdapter[]
|
||||
readonly ITotpPluginAdapter[] _pluginAdapters = new ITotpPluginAdapter[]
|
||||
{
|
||||
new TrayTotpPluginAdapter(),
|
||||
new KeeOtpPluginAdapter(),
|
||||
@@ -46,7 +47,7 @@ namespace keepass2android
|
||||
foreach (ITotpPluginAdapter adapter in _pluginAdapters)
|
||||
{
|
||||
TotpData totpData = adapter.GetTotpData(
|
||||
App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key),
|
||||
entry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key),
|
||||
pair => pair.Value.ReadString()), LocaleManager.LocalizedAppContext, false);
|
||||
if (totpData.IsTotpEntry)
|
||||
{
|
||||
|
@@ -31,12 +31,14 @@ namespace PluginTOTP
|
||||
public string TimeCorrectionUrl { get; set; }
|
||||
|
||||
public string HashAlgorithm { get; set; }
|
||||
|
||||
|
||||
public bool IsDefaultRfc6238
|
||||
{
|
||||
get { return Length == "6" && Duration == "30" && (HashAlgorithm == null || HashAlgorithm == HashSha1); }
|
||||
}
|
||||
|
||||
public List<string> InternalFields { get; set; } = new List<string>();
|
||||
|
||||
public static TotpData MakeDefaultRfc6238()
|
||||
{
|
||||
return new TotpData()
|
||||
|
@@ -31,17 +31,8 @@ namespace PluginTOTP
|
||||
_muteWarnings = muteWarnings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if specified Entry contains Settings that are not null.
|
||||
/// </summary>
|
||||
internal bool SettingsCheck(IDictionary<string, string> entryFields)
|
||||
{
|
||||
string settings;
|
||||
entryFields.TryGetValue(SettingsFieldName, out settings);
|
||||
return !String.IsNullOrEmpty(settings);
|
||||
}
|
||||
|
||||
internal bool SeedCheck(IDictionary<string, string> entryFields)
|
||||
|
||||
internal bool HasSeed(IDictionary<string, string> entryFields)
|
||||
{
|
||||
string seed;
|
||||
entryFields.TryGetValue(SeedFieldName, out seed);
|
||||
@@ -100,21 +91,23 @@ namespace PluginTOTP
|
||||
}
|
||||
|
||||
private string[] SettingsGet(IDictionary<string, string> entryFields)
|
||||
{
|
||||
return entryFields[SettingsFieldName].Split(';');
|
||||
}
|
||||
{
|
||||
return entryFields.TryGetValue(SettingsFieldName, out var settings) ? settings.Split(';') : new[] { "30", "6" };
|
||||
}
|
||||
|
||||
public TotpData GetTotpData(IDictionary<string, string> entryFields)
|
||||
{
|
||||
TotpData res = new TotpData();
|
||||
|
||||
if (SettingsCheck(entryFields) && SeedCheck(entryFields))
|
||||
if (HasSeed(entryFields))
|
||||
{
|
||||
bool ValidInterval; bool ValidLength; bool ValidUrl;
|
||||
if (SettingsValidate(entryFields, out ValidInterval, out ValidLength, out ValidUrl))
|
||||
{
|
||||
bool NoTimeCorrection = false;
|
||||
string[] Settings = SettingsGet(entryFields);
|
||||
res.InternalFields.Add(SettingsFieldName);
|
||||
res.InternalFields.Add(SeedFieldName);
|
||||
res.Duration = Settings[0];
|
||||
res.Length = Settings[1];
|
||||
if (res.Length == "S")
|
||||
|
@@ -13,7 +13,7 @@ namespace PluginTOTP
|
||||
{
|
||||
class UpdateTotpTimerTask: TimerTask
|
||||
{
|
||||
public const string TotpKey = "TOTP";
|
||||
public const string TotpKey = Kp2aTotp.TotpKey;
|
||||
private readonly Context _context;
|
||||
private readonly ITotpPluginAdapter _adapter;
|
||||
|
||||
|
@@ -6,9 +6,13 @@ using Android.OS;
|
||||
using Android.Widget;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
using KeePassLib.Utility;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
using Android.Content.Res;
|
||||
using Android.Preferences;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -339,9 +343,17 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
public virtual void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public virtual void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
activity.StartNotificationsService(false);
|
||||
//this default implementation is executed when we're opening an entry manually, i.e. without search/autofill.
|
||||
//We only activate the keyboard if this is enabled in "silent mode"
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(activity);
|
||||
bool activateKeyboard = prefs.GetBoolean("kp2a_switch_rooted", false) &&
|
||||
!prefs.GetBoolean(
|
||||
activity.GetString(Resource.String
|
||||
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||
|
||||
activity.StartNotificationsService(activateKeyboard);
|
||||
}
|
||||
|
||||
public virtual void PopulatePasswordAccessServiceIntent(Intent intent)
|
||||
@@ -353,7 +365,8 @@ namespace keepass2android
|
||||
protected static bool GetBoolFromBundle(Bundle b, string key, bool defaultValue)
|
||||
{
|
||||
bool boolValue;
|
||||
if (!Boolean.TryParse(b.GetString(key), out boolValue))
|
||||
string stringValue = b.GetString(key);
|
||||
if (!Boolean.TryParse(stringValue, out boolValue))
|
||||
{
|
||||
boolValue = defaultValue;
|
||||
}
|
||||
@@ -363,7 +376,8 @@ namespace keepass2android
|
||||
protected static int GetIntFromBundle(Bundle b, string key, int defaultValue)
|
||||
{
|
||||
int intValue;
|
||||
if (!Int32.TryParse(b.GetString(key), out intValue))
|
||||
var strValue = b.GetString(key);
|
||||
if (!Int32.TryParse(strValue, out intValue))
|
||||
{
|
||||
intValue = defaultValue;
|
||||
}
|
||||
@@ -383,7 +397,7 @@ namespace keepass2android
|
||||
/// User is about to search an entry for a given URL
|
||||
/// </summary>
|
||||
/// Derive from SelectEntryTask. This means that as soon as an Entry is opened, we're returning with
|
||||
/// ExitAfterTaskComplete. This also allows te specify the flag if we need to display the user notifications.
|
||||
/// ExitAfterTaskComplete. This also allows to specify the flag if we need to display the user notifications.
|
||||
public class SearchUrlTask: SelectEntryTask
|
||||
{
|
||||
public SearchUrlTask()
|
||||
@@ -392,8 +406,9 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
public const String UrlToSearchKey = "UrlToSearch";
|
||||
public const String AutoReturnFromQueryKey = "AutoReturnFromQuery";
|
||||
|
||||
public string UrlToSearchFor
|
||||
public string UrlToSearchFor
|
||||
{
|
||||
get;
|
||||
set;
|
||||
@@ -416,7 +431,7 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public const String AutoReturnFromQueryKey = "AutoReturnFromQuery";
|
||||
|
||||
|
||||
public bool AutoReturnFromQuery { get; set; }
|
||||
|
||||
@@ -424,15 +439,19 @@ namespace keepass2android
|
||||
{
|
||||
if (String.IsNullOrEmpty(UrlToSearchFor))
|
||||
{
|
||||
GroupActivity.Launch(act, new SelectEntryTask() { ShowUserNotifications = ShowUserNotifications}, new ActivityLaunchModeRequestCode(0));
|
||||
GroupActivity.Launch(act, new SelectEntryTask() {
|
||||
ShowUserNotifications = ShowUserNotifications,
|
||||
CopyTotpToClipboard = CopyTotpToClipboard,
|
||||
ActivateKeyboard = ActivateKeyboard
|
||||
},
|
||||
new ActivityLaunchModeRequestCode(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShareUrlResults.Launch(act, this, new ActivityLaunchModeRequestCode(0));
|
||||
}
|
||||
|
||||
|
||||
//removed. this causes an issue in the following workflow:
|
||||
//removed. this causes an issue in the following workflow:
|
||||
//When the user wants to find an entry for a URL but has the wrong database open he needs
|
||||
//to switch to another database. But the Task is removed already the first time when going through PasswordActivity
|
||||
// (with the wrong db).
|
||||
@@ -453,7 +472,7 @@ namespace keepass2android
|
||||
intent.PutExtra(UrlToSearchKey, UrlToSearchFor);
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
@@ -462,18 +481,18 @@ namespace keepass2android
|
||||
//if the database is readonly (or no URL exists), don't offer to modify the URL
|
||||
if ((App.Kp2a.CurrentDb.CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor) || keepass2android.ShareUrlResults.GetSearchResultsForUrl(UrlToSearchFor).Entries.Any(e => e == activity.Entry) ))
|
||||
{
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
return;
|
||||
}
|
||||
|
||||
AskAddUrlThenCompleteCreate(activity, UrlToSearchFor);
|
||||
AskAddUrlThenCompleteCreate(activity, UrlToSearchFor, notifyPluginsOnOpenThread);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding
|
||||
/// </summary>
|
||||
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url)
|
||||
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title));
|
||||
@@ -482,12 +501,13 @@ namespace keepass2android
|
||||
|
||||
builder.SetPositiveButton(activity.GetString(Resource.String.yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity));
|
||||
activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity, notifyPluginsOnOpenThread
|
||||
));
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(activity.GetString(Resource.String.no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
@@ -495,8 +515,46 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public class OpenSpecificEntryTask : SelectEntryTask
|
||||
{
|
||||
public OpenSpecificEntryTask()
|
||||
{
|
||||
}
|
||||
|
||||
public enum ShowUserNotificationsMode
|
||||
public const String EntryUuidKey = "EntryUuid";
|
||||
|
||||
public string EntryUuid
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override void Setup(Bundle b)
|
||||
{
|
||||
base.Setup(b);
|
||||
EntryUuid = b.GetString(EntryUuidKey);
|
||||
|
||||
}
|
||||
public override IEnumerable<IExtra> Extras
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (IExtra e in base.Extras)
|
||||
yield return e;
|
||||
|
||||
yield return new StringExtra { Key = EntryUuidKey, Value = EntryUuid };
|
||||
}
|
||||
}
|
||||
|
||||
public override void LaunchFirstGroupActivity(Activity act)
|
||||
{
|
||||
ShareUrlResults.Launch(act, this, new ActivityLaunchModeRequestCode(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum ActivationCondition
|
||||
{
|
||||
Never,
|
||||
WhenTotp,
|
||||
@@ -509,29 +567,34 @@ namespace keepass2android
|
||||
{
|
||||
public SelectEntryTask()
|
||||
{
|
||||
ShowUserNotifications = ShowUserNotificationsMode.Always;
|
||||
ShowUserNotifications = ActivationCondition.Always;
|
||||
CloseAfterCreate = true;
|
||||
ActivateKeyboard = true;
|
||||
ActivateKeyboard = ActivationCondition.Never;
|
||||
CopyTotpToClipboard = false;
|
||||
}
|
||||
|
||||
public const String ShowUserNotificationsKey = "ShowUserNotifications";
|
||||
|
||||
|
||||
|
||||
public ShowUserNotificationsMode ShowUserNotifications { get; set; }
|
||||
public ActivationCondition ShowUserNotifications { get; set; }
|
||||
|
||||
public const String CloseAfterCreateKey = "CloseAfterCreate";
|
||||
public const String ActivateKeyboardKey = "ActivateKeyboard";
|
||||
public const String CopyTotpToClipboardKey = "CopyTotpToClipboard";
|
||||
|
||||
public bool CloseAfterCreate { get; set; }
|
||||
public bool ActivateKeyboard { get; set; }
|
||||
public ActivationCondition ActivateKeyboard { get; set; }
|
||||
|
||||
public bool CopyTotpToClipboard { get; set; }
|
||||
|
||||
|
||||
public override void Setup(Bundle b)
|
||||
{
|
||||
ShowUserNotifications = (ShowUserNotificationsMode) GetIntFromBundle(b, ShowUserNotificationsKey, (int)ShowUserNotificationsMode.Always);
|
||||
ShowUserNotifications = (ActivationCondition) GetIntFromBundle(b, ShowUserNotificationsKey, (int)ActivationCondition.Always);
|
||||
CloseAfterCreate = GetBoolFromBundle(b, CloseAfterCreateKey, true);
|
||||
ActivateKeyboard = GetBoolFromBundle(b, ActivateKeyboardKey, true);
|
||||
ActivateKeyboard = (ActivationCondition)GetIntFromBundle(b, ActivateKeyboardKey, (int)ActivationCondition.Always);
|
||||
CopyTotpToClipboard = GetBoolFromBundle(b, CopyTotpToClipboardKey, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -541,31 +604,59 @@ namespace keepass2android
|
||||
{
|
||||
yield return new StringExtra { Key = ShowUserNotificationsKey, Value = ((int)ShowUserNotifications).ToString() };
|
||||
yield return new StringExtra { Key = CloseAfterCreateKey, Value = CloseAfterCreate.ToString() };
|
||||
yield return new StringExtra { Key = ActivateKeyboardKey, Value = ActivateKeyboard.ToString() };
|
||||
yield return new StringExtra { Key = ActivateKeyboardKey, Value = ((int)ActivateKeyboard).ToString() };
|
||||
yield return new StringExtra { Key = CopyTotpToClipboardKey, Value = CopyTotpToClipboard.ToString() };
|
||||
}
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
Context ctx = activity;
|
||||
if (ctx == null)
|
||||
ctx = LocaleManager.LocalizedAppContext;
|
||||
|
||||
if ((ShowUserNotifications == ShowUserNotificationsMode.Always)
|
||||
|| ((ShowUserNotifications == ShowUserNotificationsMode.WhenTotp) && new Kp2aTotp().TryGetAdapter(new PwEntryOutput(activity.Entry, App.Kp2a.CurrentDb)) != null))
|
||||
{
|
||||
//show the notifications
|
||||
activity.StartNotificationsService(ActivateKeyboard);
|
||||
}
|
||||
var pwEntryOutput = new PwEntryOutput(activity.Entry, App.Kp2a.CurrentDb);
|
||||
var totpPluginAdapter = new Kp2aTotp().TryGetAdapter(pwEntryOutput);
|
||||
bool isTotpEntry = totpPluginAdapter != null;
|
||||
|
||||
bool activateKeyboard = ActivateKeyboard == ActivationCondition.Always || (ActivateKeyboard == ActivationCondition.WhenTotp && isTotpEntry);
|
||||
|
||||
if ((ShowUserNotifications == ActivationCondition.Always)
|
||||
|| ((ShowUserNotifications == ActivationCondition.WhenTotp) && isTotpEntry)
|
||||
|| activateKeyboard)
|
||||
{
|
||||
//show the notifications
|
||||
activity.StartNotificationsService(activateKeyboard);
|
||||
}
|
||||
else
|
||||
{
|
||||
//to avoid getting into inconsistent state (LastOpenedEntry and Notifications): clear notifications:
|
||||
CopyToClipboardService.CancelNotifications(activity);
|
||||
}
|
||||
if (CloseAfterCreate)
|
||||
{
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
|
||||
if (CopyTotpToClipboard && isTotpEntry)
|
||||
{
|
||||
Dictionary<string, string> entryFields = pwEntryOutput.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString());
|
||||
var totpData= totpPluginAdapter.GetTotpData(entryFields, activity, true);
|
||||
if (totpData.IsTotpEntry)
|
||||
{
|
||||
TOTPProvider prov = new TOTPProvider(totpData);
|
||||
string totp = prov.GenerateByByte(totpData.TotpSecret);
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(activity, totp, true);
|
||||
|
||||
Toast.MakeText(activity, activity.GetString(Resource.String.TotpCopiedToClipboard),
|
||||
ToastLength.Long).Show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (CloseAfterCreate)
|
||||
{
|
||||
//give plugins and TOTP time to do their work:
|
||||
notifyPluginsOnOpenThread.Join(TimeSpan.FromSeconds(1));
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -629,8 +720,8 @@ namespace keepass2android
|
||||
public class CreateEntryThenCloseTask: AppTask
|
||||
{
|
||||
public CreateEntryThenCloseTask()
|
||||
{
|
||||
ShowUserNotifications = ShowUserNotificationsMode.Always;
|
||||
{
|
||||
ShowUserNotifications = ActivationCondition.Always;
|
||||
}
|
||||
|
||||
public override bool CanActivateSearchViewOnStart
|
||||
@@ -670,13 +761,13 @@ namespace keepass2android
|
||||
|
||||
public IList<string> ProtectedFieldsList { get; set; }
|
||||
|
||||
public ShowUserNotificationsMode ShowUserNotifications { get; set; }
|
||||
public ActivationCondition ShowUserNotifications { get; set; }
|
||||
|
||||
|
||||
public override void Setup(Bundle b)
|
||||
{
|
||||
|
||||
ShowUserNotifications = (ShowUserNotificationsMode)GetIntFromBundle(b,ShowUserNotificationsKey, (int)ShowUserNotificationsMode.Always);
|
||||
ShowUserNotifications = (ActivationCondition)GetIntFromBundle(b,ShowUserNotificationsKey, (int)ActivationCondition.Always);
|
||||
|
||||
Url = b.GetString(UrlKey);
|
||||
AllFields = b.GetString(AllFieldsKey);
|
||||
@@ -724,15 +815,15 @@ namespace keepass2android
|
||||
public override void AfterAddNewEntry(EntryEditActivity entryEditActivity, PwEntry newEntry)
|
||||
{
|
||||
EntryActivity.Launch(entryEditActivity, newEntry, -1,
|
||||
new SelectEntryTask { ShowUserNotifications = this.ShowUserNotifications},
|
||||
new SelectEntryTask() { ShowUserNotifications = this.ShowUserNotifications, ActivateKeyboard = ActivationCondition.Never },
|
||||
ActivityFlags.ForwardResult);
|
||||
//no need to call Finish here, that's done in EntryEditActivity ("closeOrShowError")
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
//if the user selects an entry before creating the new one, we're not closing the app
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -227,6 +227,7 @@
|
||||
<Compile Include="fileselect\FileSelectActivity.cs" />
|
||||
<Compile Include="fileselect\FileDbHelper.cs" />
|
||||
<Compile Include="search\SearchProvider.cs" />
|
||||
<Compile Include="search\SearchTotpResults.cs" />
|
||||
<Compile Include="SelectStorageLocationActivity.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillFieldMetadata.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillFieldMetadataCollection.cs" />
|
||||
@@ -1985,6 +1986,21 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_pcloudall.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_entry_totp.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_fab_search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_fab_search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_fab_totp.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_fab_totp.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
162
src/keepass2android/search/SearchTotpResults.cs
Normal file
162
src/keepass2android/search/SearchTotpResults.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.view;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android.search
|
||||
{
|
||||
/// <summary>
|
||||
/// Activity to show search results
|
||||
/// </summary>
|
||||
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
|
||||
public class SearchTotpResults : GroupBaseActivity
|
||||
{
|
||||
|
||||
public static void Launch(Activity act, AppTask appTask, ActivityFlags? flags = null)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(SearchTotpResults));
|
||||
|
||||
|
||||
if (flags != null)
|
||||
i.SetFlags((ActivityFlags)flags);
|
||||
|
||||
appTask.ToIntent(i);
|
||||
if (flags != null && (((ActivityFlags)flags) | ActivityFlags.ForwardResult) == ActivityFlags.ForwardResult)
|
||||
act.StartActivity(i);
|
||||
else
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
public override bool MayPreviewTotp
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
|
||||
if ( IsFinishing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetResult(KeePass.ExitNormal);
|
||||
|
||||
// Likely the app has been killed exit the activity
|
||||
if (!App.Kp2a.DatabaseIsUnlocked)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
|
||||
Group = new PwGroup()
|
||||
{
|
||||
Name = GetString(Resource.String.TOTP)
|
||||
};
|
||||
try
|
||||
{
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
foreach (var entry in db.EntriesById.Values)
|
||||
{
|
||||
var totpData = new Kp2aTotp().TryGetTotpData(new PwEntryOutput(entry, db));
|
||||
if (totpData?.IsTotpEntry == true)
|
||||
Group.AddEntry(entry, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Group == null || (!Group.Entries.Any()))
|
||||
{
|
||||
SetContentView(Resource.Layout.group_empty);
|
||||
}
|
||||
|
||||
SetGroupTitle();
|
||||
|
||||
FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group);
|
||||
|
||||
}
|
||||
|
||||
public override bool EntriesBelongToCurrentDatabaseOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override ElementAndDatabaseId FullGroupId
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override void OnCreateContextMenu(IContextMenu menu, View v,
|
||||
IContextMenuContextMenuInfo menuInfo)
|
||||
{
|
||||
|
||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
ClickView cv = (ClickView) acmi.TargetView;
|
||||
cv.OnCreateMenu(menu, menuInfo);
|
||||
}
|
||||
|
||||
public override bool OnContextItemSelected(IMenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.MenuInfo;
|
||||
ClickView cv = (ClickView) acmi.TargetView;
|
||||
|
||||
bool result;
|
||||
|
||||
return cv.OnContextItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
public override bool OnSearchRequested()
|
||||
{
|
||||
Intent i = new Intent(this, typeof(SearchActivity));
|
||||
this.AppTask.ToIntent(i);
|
||||
i.SetFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ using AndroidX.AutoFill.Inline;
|
||||
using AndroidX.AutoFill.Inline.V1;
|
||||
using Java.Util.Concurrent.Atomic;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
using KeePassLib;
|
||||
using Kp2aAutofillParser;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
@@ -29,7 +30,7 @@ namespace keepass2android.services.AutofillBase
|
||||
PendingIntent GetAuthPendingIntentForResponse(Context context, string query, string queryDomain, string queryPackage,
|
||||
bool isManualRequest, bool autoReturnFromQuery, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
PendingIntent GetAuthPendingIntentForWarning(Context context, string query, string queryDomain, string queryPackage, AutofillServiceBase.DisplayWarning warning);
|
||||
PendingIntent GetAuthPendingIntentForWarning(Context context, PwUuid entryUuid, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
PendingIntent GetDisablePendingIntentForResponse(Context context, string query,
|
||||
bool isManualRequest, bool isDisable);
|
||||
@@ -262,33 +263,42 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
List<Dataset> result = new List<Dataset>();
|
||||
Kp2aLog.Log("AF: BuildEntryDatasets");
|
||||
var suggestedEntries = GetSuggestedEntries(query).ToDictionary(e => e.DatasetName, e => e);
|
||||
Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> suggestedEntries = GetSuggestedEntries(query);
|
||||
Kp2aLog.Log("AF: BuildEntryDatasets found " + suggestedEntries.Count + " entries");
|
||||
|
||||
int count = 0;
|
||||
foreach (var filledAutofillFieldCollection in suggestedEntries.Values)
|
||||
|
||||
var totpHelper = new Kp2aTotp();
|
||||
|
||||
foreach (var kvp in suggestedEntries)
|
||||
{
|
||||
var filledAutofillFieldCollection = kvp.Value;
|
||||
PwEntryOutput entry = kvp.Key;
|
||||
|
||||
if (filledAutofillFieldCollection == null)
|
||||
continue;
|
||||
|
||||
var inlinePresentationSpec = AutofillHelper.ExtractSpec(inlinePresentationSpecs, count);
|
||||
|
||||
if (warning == DisplayWarning.None)
|
||||
if ((warning == DisplayWarning.None)
|
||||
&& (totpHelper.TryGetAdapter(entry) == null))
|
||||
{
|
||||
|
||||
//no special dataset, we can immediately return the field collection
|
||||
FilledAutofillFieldCollection<ViewNodeInputField> partitionData =
|
||||
AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, parser.AutofillFields.FocusedAutofillCanonicalHints);
|
||||
|
||||
Kp2aLog.Log("AF: Add dataset");
|
||||
|
||||
result.Add(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder,
|
||||
result.Add(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder,
|
||||
inlinePresentationSpec));
|
||||
}
|
||||
else
|
||||
{
|
||||
//return an "auth" dataset (actually for just warning the user in case domain/package dont match)
|
||||
|
||||
//return an "auth" dataset (actually for just warning the user in case domain/package dont match and/or to make sure that we open the EntryActivity,
|
||||
// thus opening the entry notification in case of TOTP)
|
||||
PendingIntent pendingIntent =
|
||||
IntentBuilder.GetAuthPendingIntentForWarning(this, query, queryDomain, queryPackage, warning);
|
||||
IntentBuilder.GetAuthPendingIntentForWarning(this, entry.Uuid, warning);
|
||||
var datasetName = filledAutofillFieldCollection.DatasetName;
|
||||
if (datasetName == null)
|
||||
{
|
||||
@@ -320,7 +330,7 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
}
|
||||
|
||||
protected abstract List<FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query);
|
||||
protected abstract Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query);
|
||||
|
||||
public enum DisplayWarning
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
protected Intent ReplyIntent;
|
||||
|
||||
|
||||
public static string ExtraUuidString => "EXTRA_UUID_STRING";
|
||||
public static string ExtraQueryString => "EXTRA_QUERY_STRING";
|
||||
public static string ExtraQueryPackageString => "EXTRA_QUERY_PACKAGE_STRING";
|
||||
public static string ExtraQueryDomainString => "EXTRA_QUERY_DOMAIN_STRING";
|
||||
@@ -50,9 +50,10 @@ namespace keepass2android.services.AutofillBase
|
||||
}
|
||||
|
||||
string requestedUrl = Intent.GetStringExtra(ExtraQueryString);
|
||||
if (requestedUrl == null)
|
||||
string requestedUuid = Intent.GetStringExtra(ExtraUuidString);
|
||||
if (requestedUrl == null && requestedUuid == null)
|
||||
{
|
||||
Kp2aLog.Log("ChooseForAutofillActivityBase: no requestedUrl ");
|
||||
Kp2aLog.Log("ChooseForAutofillActivityBase: no requestedUrl and no requestedUuid");
|
||||
Toast.MakeText(this, "Cannot execute query for null.", ToastLength.Long).Show();
|
||||
RestartApp();
|
||||
return;
|
||||
@@ -134,18 +135,30 @@ namespace keepass2android.services.AutofillBase
|
||||
private void Proceed()
|
||||
{
|
||||
string requestedUrl = Intent.GetStringExtra(ExtraQueryString);
|
||||
string requestedUuid = Intent.GetStringExtra(ExtraUuidString);
|
||||
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true), Intent.GetBooleanExtra(ExtraUseLastOpenedEntry, false));
|
||||
if (i == null)
|
||||
if (requestedUuid != null)
|
||||
{
|
||||
//GetQueryIntent returns null if no query is required
|
||||
ReturnSuccess();
|
||||
var i = GetOpenEntryIntent(requestedUuid);
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
}
|
||||
else
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
{
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true), Intent.GetBooleanExtra(ExtraUseLastOpenedEntry, false));
|
||||
if (i == null)
|
||||
{
|
||||
//GetQueryIntent returns null if no query is required
|
||||
ReturnSuccess();
|
||||
}
|
||||
else
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected abstract Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry);
|
||||
protected abstract Intent GetOpenEntryIntent(string entryUuid);
|
||||
|
||||
protected void RestartApp()
|
||||
{
|
||||
|
@@ -501,24 +501,8 @@ namespace keepass2android
|
||||
if (hasKeyboardDataNow)
|
||||
{
|
||||
notBuilder.AddKeyboardAccess();
|
||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||
{
|
||||
//switch rooted
|
||||
bool onlySwitchOnSearch = prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||
if (activateKeyboard || (!onlySwitchOnSearch))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||
// automatically bring up the Keyboard selection dialog
|
||||
if ((activateKeyboard) && prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
if (activateKeyboard)
|
||||
ActivateKp2aKeyboard();
|
||||
|
||||
}
|
||||
|
||||
@@ -548,31 +532,6 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
public void ActivateKeyboardIfAppropriate(bool closeAfterCreate, ISharedPreferences prefs)
|
||||
{
|
||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||
{
|
||||
//switch rooted
|
||||
bool onlySwitchOnSearch = prefs.GetBoolean(
|
||||
GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||
if (closeAfterCreate || (!onlySwitchOnSearch))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||
// automatically bring up the Keyboard selection dialog
|
||||
if ((closeAfterCreate) &&
|
||||
prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key),
|
||||
Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||
{
|
||||
ActivateKp2aKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ClearNotifications()
|
||||
{
|
||||
// Notification Manager
|
||||
@@ -587,6 +546,7 @@ namespace keepass2android
|
||||
return hadKeyboardData;
|
||||
}
|
||||
|
||||
|
||||
bool MakeAccessibleForKeyboard(PwEntryOutput entry, string searchUrl)
|
||||
{
|
||||
#if EXCLUDE_KEYBOARD
|
||||
@@ -595,38 +555,41 @@ namespace keepass2android
|
||||
bool hasData = false;
|
||||
Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder();
|
||||
|
||||
String[] keys = {PwDefs.UserNameField,
|
||||
String[] standardKeys = {PwDefs.UserNameField,
|
||||
PwDefs.PasswordField,
|
||||
Kp2aTotp.TotpKey,
|
||||
PwDefs.UrlField,
|
||||
PwDefs.NotesField,
|
||||
PwDefs.TitleField
|
||||
};
|
||||
int[] resIds = {Resource.String.entry_user_name,
|
||||
Resource.String.entry_password,
|
||||
0,
|
||||
Resource.String.entry_url,
|
||||
Resource.String.entry_comment,
|
||||
Resource.String.entry_title };
|
||||
|
||||
//add standard fields:
|
||||
int i = 0;
|
||||
foreach (string key in keys)
|
||||
foreach (string key in standardKeys)
|
||||
{
|
||||
String value = entry.OutputStrings.ReadSafe(key);
|
||||
|
||||
if (value.Length > 0)
|
||||
{
|
||||
kbdataBuilder.AddString(key, GetString(resIds[i]), value);
|
||||
kbdataBuilder.AddString(key, resIds[i] > 0 ? GetString(resIds[i]) : key, value);
|
||||
hasData = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
//add additional fields:
|
||||
var totpData = new Kp2aTotp().TryGetTotpData(entry);
|
||||
foreach (var pair in entry.OutputStrings)
|
||||
{
|
||||
var key = pair.Key;
|
||||
var value = pair.Value.ReadString();
|
||||
|
||||
if (!PwDefs.IsStandardField(key))
|
||||
if (!standardKeys.Contains(key) && totpData?.InternalFields.Contains(key) != true)
|
||||
{
|
||||
kbdataBuilder.AddString(pair.Key, pair.Key, value);
|
||||
hasData = true;
|
||||
@@ -865,14 +828,9 @@ namespace keepass2android
|
||||
{
|
||||
//let's bring up the keyboard switching dialog.
|
||||
//Unfortunately this no longer works starting with Android 9 if our app is not in foreground.
|
||||
bool mustUseHelperActivity = false;
|
||||
if ((int)Build.VERSION.SdkInt >= 28)
|
||||
{
|
||||
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
|
||||
ActivityManager.GetMyMemoryState(appProcessInfo);
|
||||
//at least on Samsung devices, we always need the helper activity
|
||||
mustUseHelperActivity = (appProcessInfo.Importance != Importance.Foreground) || (Build.Manufacturer != "Google");
|
||||
}
|
||||
//first it seemed to be required for Samsung mostly, but there are use cases where it is required for other devices as well.
|
||||
//Let's be sure and use the helper activity.
|
||||
bool mustUseHelperActivity = (int)Build.VERSION.SdkInt >= 28;
|
||||
if (mustUseHelperActivity)
|
||||
{
|
||||
try
|
||||
|
@@ -10,6 +10,7 @@ using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using AndroidX.Preference;
|
||||
using KeePass.Util.Spr;
|
||||
using keepass2android.services.AutofillBase;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
@@ -23,9 +24,36 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
[Activity(Label = "@string/app_name",
|
||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||
Theme = "@style/MyTheme_ActionBar",
|
||||
WindowSoftInputMode = SoftInput.AdjustResize,
|
||||
Permission = "keepass2android." + AppNames.PackagePart + ".permission.Kp2aChooseAutofill")]
|
||||
public class ChooseForAutofillActivity : ChooseForAutofillActivityBase
|
||||
{
|
||||
public bool ActivateKeyboardWhenTotpPreference
|
||||
{
|
||||
get
|
||||
{
|
||||
return PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean("AutoFillTotp_prefs_ActivateKeyboard_key", false);
|
||||
}
|
||||
}
|
||||
public bool CopyTotpToClipboardPreference
|
||||
{
|
||||
get
|
||||
{
|
||||
return PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean("AutoFillTotp_prefs_CopyTotpToClipboard_key", true);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowNotificationPreference
|
||||
{
|
||||
get
|
||||
{
|
||||
return PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean("AutoFillTotp_prefs_ShowNotification_key", true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry)
|
||||
{
|
||||
if (useLastOpenedEntry && (App.Kp2a.LastOpenedEntry?.SearchUrl == requestedUrl))
|
||||
@@ -36,7 +64,33 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new SearchUrlTask() { UrlToSearchFor = requestedUrl, ShowUserNotifications = ShowUserNotificationsMode.WhenTotp, AutoReturnFromQuery = autoReturnFromQuery, ActivateKeyboard = false };
|
||||
var task = new SearchUrlTask()
|
||||
{
|
||||
UrlToSearchFor = requestedUrl,
|
||||
AutoReturnFromQuery = autoReturnFromQuery
|
||||
};
|
||||
SetTotpDependantActionsOnTask(task);
|
||||
|
||||
task.ToIntent(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
private void SetTotpDependantActionsOnTask(SelectEntryTask task)
|
||||
{
|
||||
task.ShowUserNotifications =
|
||||
ShowNotificationPreference ? ActivationCondition.WhenTotp : ActivationCondition.Never;
|
||||
task.CopyTotpToClipboard = CopyTotpToClipboardPreference;
|
||||
task.ActivateKeyboard = ActivateKeyboardWhenTotpPreference
|
||||
? ActivationCondition.WhenTotp
|
||||
: ActivationCondition.Never;
|
||||
}
|
||||
|
||||
protected override Intent GetOpenEntryIntent(string entryUuid)
|
||||
{
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new OpenSpecificEntryTask() { EntryUuid = entryUuid };
|
||||
SetTotpDependantActionsOnTask(task);
|
||||
task.ToIntent(i);
|
||||
return i;
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using keepass2android.services.AutofillBase;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
@@ -34,24 +35,29 @@ namespace keepass2android.services
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query)
|
||||
protected override Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query)
|
||||
{
|
||||
if (!App.Kp2a.DatabaseIsUnlocked)
|
||||
return new List<FilledAutofillFieldCollection<ViewNodeInputField>>();
|
||||
return new Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>>();
|
||||
var foundEntries = (ShareUrlResults.GetSearchResultsForUrl(query)?.Entries ?? new PwObjectList<PwEntry>())
|
||||
.Select(e => new PwEntryOutput(e, App.Kp2a.FindDatabaseForElement(e)))
|
||||
.ToList();
|
||||
|
||||
if (App.Kp2a.LastOpenedEntry?.SearchUrl == query)
|
||||
{
|
||||
foundEntries.Clear();
|
||||
foundEntries.Add(App.Kp2a.LastOpenedEntry);
|
||||
foundEntries.Add(App.Kp2a.LastOpenedEntry?.Entry);
|
||||
}
|
||||
|
||||
//it seems like at least with Firefox we can have at most 3 datasets. Reserve space for the disable/enable dataset and the "fill with KP2A" which allows to select another item
|
||||
//so take only 1:
|
||||
return foundEntries.Take(1).Select(e => ChooseForAutofillActivity.GetFilledAutofillFieldCollectionFromEntry(e, this))
|
||||
.ToList();
|
||||
int numDisableDatasets = 0;
|
||||
if (!PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.NoAutofillDisabling_key), false))
|
||||
numDisableDatasets = 1;
|
||||
|
||||
//it seems like at least with Firefox we can have at most 3 datasets. Reserve space for the disable dataset and the "fill with KP2A" which allows to select another item
|
||||
return foundEntries.Take(2-numDisableDatasets)
|
||||
.Select(e => new PwEntryOutput(e, App.Kp2a.FindDatabaseForElement(e)))
|
||||
.ToDictionary(e => e,
|
||||
e => ChooseForAutofillActivity.GetFilledAutofillFieldCollectionFromEntry(e, this));
|
||||
}
|
||||
|
||||
protected override void HandleSaveRequest(StructureParser parser, StructureParser.AutofillTargetId query)
|
||||
|
@@ -9,6 +9,7 @@ using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.services.AutofillBase;
|
||||
using keepass2android.services.Kp2aAutofill;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android.services
|
||||
{
|
||||
@@ -29,16 +30,14 @@ namespace keepass2android.services
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Mutable));
|
||||
}
|
||||
|
||||
public PendingIntent GetAuthPendingIntentForWarning(Context context, string query, string queryDomain, string queryPackage,
|
||||
public PendingIntent GetAuthPendingIntentForWarning(Context context,PwUuid entryUuid,
|
||||
AutofillServiceBase.DisplayWarning warning)
|
||||
{
|
||||
Intent intent = new Intent(context, typeof(ChooseForAutofillActivity));
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryDomainString, queryDomain);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryPackageString, queryPackage);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraUuidString, entryUuid.ToHexString());
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraDisplayWarning, (int)warning);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraUseLastOpenedEntry, true);
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Immutable));
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Mutable));
|
||||
}
|
||||
|
||||
public PendingIntent GetDisablePendingIntentForResponse(Context context, string query,
|
||||
|
@@ -6,8 +6,10 @@ using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using Android.Support.V4.Content;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
@@ -30,10 +32,12 @@ namespace keepass2android
|
||||
public Dictionary<string, bool> DisabledQueriesValues = new Dictionary<string, bool>();
|
||||
|
||||
private readonly AutofillDisabledQueriesPreference _pref;
|
||||
private readonly Context _context;
|
||||
|
||||
public DisabledQueryPreferenceScreenAdapter(AutofillDisabledQueriesPreference pref, Context context)
|
||||
{
|
||||
_pref = pref;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +45,25 @@ namespace keepass2android
|
||||
{
|
||||
private TextView text = null;
|
||||
private CheckBox checkbox = null;
|
||||
|
||||
public CustomHolder(View row, int position, AutofillDisabledQueriesPreference pref)
|
||||
|
||||
public CustomHolder(View row, int position, AutofillDisabledQueriesPreference pref, Context context)
|
||||
{
|
||||
text = (TextView) row.FindViewById(Resource.Id.disabled_query_text);
|
||||
text.Text = pref.DisabledQueries[position].DisplayName;
|
||||
TypedValue typedValue = new TypedValue();
|
||||
|
||||
Resources.Theme theme = context.Theme;
|
||||
if (theme != null)
|
||||
{
|
||||
theme.ResolveAttribute(Android.Resource.Attribute.TextColorPrimary, typedValue, true);
|
||||
using (TypedArray arr = context.ObtainStyledAttributes(typedValue.Data, new int[] { Android.Resource.Attribute.TextColorPrimary }))
|
||||
{
|
||||
var primaryColor = arr.GetColorStateList(0);
|
||||
text.SetTextColor(primaryColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
checkbox = (CheckBox) row.FindViewById(Resource.Id.disabled_query_checkbox);
|
||||
checkbox.Id = position;
|
||||
@@ -79,7 +97,7 @@ namespace keepass2android
|
||||
int p = position;
|
||||
row = LayoutInflater.From(_pref.Context)
|
||||
.Inflate(Resource.Layout.disabled_queries_preference_row, parent, false);
|
||||
holder = new CustomHolder(row, position, _pref);
|
||||
holder = new CustomHolder(row, position, _pref, _context);
|
||||
|
||||
row.Tag = holder;
|
||||
|
||||
|
@@ -26,6 +26,10 @@ using Android.Text;
|
||||
using Android.Text.Style;
|
||||
using Android.Preferences;
|
||||
using KeePass.Util.Spr;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
using PluginTOTP;
|
||||
using Android.Content;
|
||||
using System.ComponentModel;
|
||||
|
||||
|
||||
namespace keepass2android.view
|
||||
@@ -37,8 +41,11 @@ namespace keepass2android.view
|
||||
private readonly TextView _textView;
|
||||
private readonly TextView _textviewDetails;
|
||||
private readonly TextView _textgroupFullPath;
|
||||
private readonly ProgressBar _totpCountdown;
|
||||
private readonly TextView _totpText;
|
||||
private readonly LinearLayout _totpLayout;
|
||||
|
||||
private int _pos;
|
||||
private int _pos;
|
||||
|
||||
private int? _defaultTextColor;
|
||||
|
||||
@@ -82,7 +89,18 @@ namespace keepass2android.view
|
||||
_textgroupFullPath = (TextView)ev.FindViewById(Resource.Id.group_detail);
|
||||
_textgroupFullPath.TextSize = PrefsUtil.GetListDetailTextSize(groupActivity);
|
||||
|
||||
_showDetail = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean(
|
||||
_totpCountdown = ev.FindViewById<ProgressBar>(Resource.Id.TotpCountdownProgressBar);
|
||||
_totpText = ev.FindViewById<TextView>(Resource.Id.totp_text);
|
||||
_totpLayout = ev.FindViewById<LinearLayout>(Resource.Id.totp_layout);
|
||||
|
||||
_totpLayout.LongClick += (sender, args) =>
|
||||
{
|
||||
string totp = UpdateTotp();
|
||||
if (!String.IsNullOrEmpty(totp))
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(_groupActivity, totp, true);
|
||||
};
|
||||
|
||||
_showDetail = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean(
|
||||
groupActivity.GetString(Resource.String.ShowUsernameInList_key),
|
||||
Resources.GetBoolean(Resource.Boolean.ShowUsernameInList_default));
|
||||
|
||||
@@ -112,20 +130,20 @@ namespace keepass2android.view
|
||||
ev.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible;
|
||||
ev.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible;
|
||||
|
||||
Database db = App.Kp2a.FindDatabaseForElement(_entry);
|
||||
_db = App.Kp2a.FindDatabaseForElement(_entry);
|
||||
|
||||
ImageView iv = (ImageView)ev.FindViewById(Resource.Id.icon);
|
||||
bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now;
|
||||
if (isExpired)
|
||||
{
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
} else
|
||||
{
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
}
|
||||
|
||||
String title = pw.Strings.ReadSafe(PwDefs.TitleField);
|
||||
title = SprEngine.Compile(title, new SprContext(_entry, db.KpDatabase, SprCompileFlags.All));
|
||||
title = SprEngine.Compile(title, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All));
|
||||
var str = new SpannableString(title);
|
||||
|
||||
if (isExpired)
|
||||
@@ -146,7 +164,7 @@ namespace keepass2android.view
|
||||
_textView.SetTextColor(new Color((int)_defaultTextColor));
|
||||
|
||||
String detail = pw.Strings.ReadSafe(PwDefs.UserNameField);
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, db.KpDatabase, SprCompileFlags.All));
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All));
|
||||
|
||||
if ((_showDetail == false) || (String.IsNullOrEmpty(detail)))
|
||||
{
|
||||
@@ -173,7 +191,7 @@ namespace keepass2android.view
|
||||
String groupDetail = pw.ParentGroup.GetFullPath();
|
||||
if (App.Kp2a.OpenDatabases.Count() > 1)
|
||||
{
|
||||
groupDetail += "(" + App.Kp2a.GetFileStorage(db.Ioc).GetDisplayName(db.Ioc) + ")";
|
||||
groupDetail += "(" + App.Kp2a.GetFileStorage(_db.Ioc).GetDisplayName(_db.Ioc) + ")";
|
||||
}
|
||||
|
||||
var strGroupDetail = new SpannableString (groupDetail);
|
||||
@@ -186,7 +204,16 @@ namespace keepass2android.view
|
||||
_textgroupFullPath.Visibility = ViewStates.Visible;
|
||||
}
|
||||
|
||||
}
|
||||
//try to get totp data
|
||||
UpdateTotp();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ConvertView(PwEntry pw, int pos)
|
||||
{
|
||||
@@ -248,6 +275,42 @@ namespace keepass2android.view
|
||||
{
|
||||
LaunchEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TotpData _totpData;
|
||||
|
||||
private Database _db;
|
||||
|
||||
public string UpdateTotp()
|
||||
{
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(_groupActivity);
|
||||
bool showTotpDefault = _groupActivity.MayPreviewTotp;
|
||||
|
||||
|
||||
if (showTotpDefault)
|
||||
_totpData = new Kp2aTotp().TryGetTotpData(new PwEntryOutput(_entry, _db));
|
||||
else
|
||||
_totpData = null;
|
||||
|
||||
if (_totpData?.IsTotpEntry != true)
|
||||
{
|
||||
_totpLayout.Visibility = ViewStates.Gone;
|
||||
return null;
|
||||
}
|
||||
|
||||
_totpLayout.Visibility = ViewStates.Visible;
|
||||
|
||||
TOTPProvider prov = new TOTPProvider(_totpData);
|
||||
string totp = prov.GenerateByByte(_totpData.TotpSecret);
|
||||
|
||||
_totpText.Text = totp;
|
||||
var progressBar = _totpCountdown;
|
||||
progressBar.Progress = prov.Timer;
|
||||
progressBar.Max = prov.Duration;
|
||||
|
||||
return totp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user