mirror of
https://github.com/bitwarden/mobile
synced 2025-12-15 07:43:37 +00:00
log some events
This commit is contained in:
@@ -120,6 +120,7 @@
|
|||||||
<Compile Include="Push\FirebaseInstanceIdService.cs" />
|
<Compile Include="Push\FirebaseInstanceIdService.cs" />
|
||||||
<Compile Include="Push\FirebaseMessagingService.cs" />
|
<Compile Include="Push\FirebaseMessagingService.cs" />
|
||||||
<Compile Include="Receivers\ClearClipboardAlarmReceiver.cs" />
|
<Compile Include="Receivers\ClearClipboardAlarmReceiver.cs" />
|
||||||
|
<Compile Include="Receivers\EventUploadReceiver.cs" />
|
||||||
<Compile Include="Receivers\LockAlarmReceiver.cs" />
|
<Compile Include="Receivers\LockAlarmReceiver.cs" />
|
||||||
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
||||||
<Compile Include="Renderers\CipherViewCellRenderer.cs" />
|
<Compile Include="Renderers\CipherViewCellRenderer.cs" />
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ namespace Bit.Droid
|
|||||||
private IAppIdService _appIdService;
|
private IAppIdService _appIdService;
|
||||||
private IStorageService _storageService;
|
private IStorageService _storageService;
|
||||||
private IStateService _stateService;
|
private IStateService _stateService;
|
||||||
|
private IEventService _eventService;
|
||||||
private PendingIntent _lockAlarmPendingIntent;
|
private PendingIntent _lockAlarmPendingIntent;
|
||||||
private PendingIntent _clearClipboardPendingIntent;
|
private PendingIntent _clearClipboardPendingIntent;
|
||||||
|
private PendingIntent _eventUploadPendingIntent;
|
||||||
private AppOptions _appOptions;
|
private AppOptions _appOptions;
|
||||||
private string _activityKey = $"{nameof(MainActivity)}_{Java.Lang.JavaSystem.CurrentTimeMillis().ToString()}";
|
private string _activityKey = $"{nameof(MainActivity)}_{Java.Lang.JavaSystem.CurrentTimeMillis().ToString()}";
|
||||||
private Java.Util.Regex.Pattern _otpPattern =
|
private Java.Util.Regex.Pattern _otpPattern =
|
||||||
@@ -48,6 +50,9 @@ namespace Bit.Droid
|
|||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
|
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
|
||||||
|
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
|
||||||
|
PendingIntentFlags.UpdateCurrent);
|
||||||
var alarmIntent = new Intent(this, typeof(LockAlarmReceiver));
|
var alarmIntent = new Intent(this, typeof(LockAlarmReceiver));
|
||||||
_lockAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent,
|
_lockAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent,
|
||||||
PendingIntentFlags.UpdateCurrent);
|
PendingIntentFlags.UpdateCurrent);
|
||||||
@@ -65,6 +70,7 @@ namespace Bit.Droid
|
|||||||
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
|
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
|
||||||
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||||
|
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
|
|
||||||
TabLayoutResource = Resource.Layout.Tabbar;
|
TabLayoutResource = Resource.Layout.Tabbar;
|
||||||
ToolbarResource = Resource.Layout.Toolbar;
|
ToolbarResource = Resource.Layout.Toolbar;
|
||||||
@@ -91,10 +97,10 @@ namespace Bit.Droid
|
|||||||
{
|
{
|
||||||
if(message.Command == "scheduleLockTimer")
|
if(message.Command == "scheduleLockTimer")
|
||||||
{
|
{
|
||||||
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
var lockOptionMinutes = (int)message.Data;
|
var lockOptionMinutes = (int)message.Data;
|
||||||
var lockOptionMs = lockOptionMinutes * 60000;
|
var lockOptionMs = lockOptionMinutes * 60000;
|
||||||
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + lockOptionMs + 10;
|
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + lockOptionMs + 10;
|
||||||
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
|
||||||
alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _lockAlarmPendingIntent);
|
alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _lockAlarmPendingIntent);
|
||||||
}
|
}
|
||||||
else if(message.Command == "cancelLockTimer")
|
else if(message.Command == "cancelLockTimer")
|
||||||
@@ -102,6 +108,14 @@ namespace Bit.Droid
|
|||||||
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
alarmManager.Cancel(_lockAlarmPendingIntent);
|
alarmManager.Cancel(_lockAlarmPendingIntent);
|
||||||
}
|
}
|
||||||
|
else if(message.Command == "startEventTimer")
|
||||||
|
{
|
||||||
|
StartEventAlarm();
|
||||||
|
}
|
||||||
|
else if(message.Command == "stopEventTimer")
|
||||||
|
{
|
||||||
|
var task = StopEventAlarmAsync();
|
||||||
|
}
|
||||||
else if(message.Command == "finishMainActivity")
|
else if(message.Command == "finishMainActivity")
|
||||||
{
|
{
|
||||||
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => Finish());
|
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => Finish());
|
||||||
@@ -372,5 +386,18 @@ namespace Bit.Droid
|
|||||||
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
alarmManager.Set(AlarmType.Rtc, triggerMs, _clearClipboardPendingIntent);
|
alarmManager.Set(AlarmType.Rtc, triggerMs, _clearClipboardPendingIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StartEventAlarm()
|
||||||
|
{
|
||||||
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
|
alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtime, 120000, 300000, _eventUploadPendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StopEventAlarmAsync()
|
||||||
|
{
|
||||||
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
|
alarmManager.Cancel(_eventUploadPendingIntent);
|
||||||
|
await _eventService.UploadEventsAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/Android/Receivers/EventUploadReceiver.cs
Normal file
16
src/Android/Receivers/EventUploadReceiver.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using Bit.Core.Abstractions;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
|
namespace Bit.Droid.Receivers
|
||||||
|
{
|
||||||
|
[BroadcastReceiver(Name = "com.x8bit.bitwarden.EventUploadReceiver", Exported = false)]
|
||||||
|
public class EventUploadReceiver : BroadcastReceiver
|
||||||
|
{
|
||||||
|
public async override void OnReceive(Context context, Intent intent)
|
||||||
|
{
|
||||||
|
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
|
await eventService.UploadEventsAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -173,6 +173,7 @@ namespace Bit.App
|
|||||||
SyncIfNeeded();
|
SyncIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_messagingService.Send("startEventTimer");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override void OnSleep()
|
protected async override void OnSleep()
|
||||||
@@ -184,6 +185,7 @@ namespace Bit.App
|
|||||||
}
|
}
|
||||||
SetTabsPageFromAutofill();
|
SetTabsPageFromAutofill();
|
||||||
await HandleLockingAsync();
|
await HandleLockingAsync();
|
||||||
|
_messagingService.Send("stopEventTimer");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
@@ -198,6 +200,7 @@ namespace Bit.App
|
|||||||
private async void ResumedAsync()
|
private async void ResumedAsync()
|
||||||
{
|
{
|
||||||
_messagingService.Send("cancelLockTimer");
|
_messagingService.Send("cancelLockTimer");
|
||||||
|
_messagingService.Send("startEventTimer");
|
||||||
await ClearCacheIfNeededAsync();
|
await ClearCacheIfNeededAsync();
|
||||||
await TryClearCiphersCacheAsync();
|
await TryClearCiphersCacheAsync();
|
||||||
Prime();
|
Prime();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace Bit.App.Pages
|
|||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
private readonly IAuditService _auditService;
|
private readonly IAuditService _auditService;
|
||||||
private readonly IMessagingService _messagingService;
|
private readonly IMessagingService _messagingService;
|
||||||
|
private readonly IEventService _eventService;
|
||||||
private CipherView _cipher;
|
private CipherView _cipher;
|
||||||
private bool _showNotesSeparator;
|
private bool _showNotesSeparator;
|
||||||
private bool _showPassword;
|
private bool _showPassword;
|
||||||
@@ -34,6 +35,7 @@ namespace Bit.App.Pages
|
|||||||
private int _folderSelectedIndex;
|
private int _folderSelectedIndex;
|
||||||
private int _ownershipSelectedIndex;
|
private int _ownershipSelectedIndex;
|
||||||
private bool _hasCollections;
|
private bool _hasCollections;
|
||||||
|
private string _previousCipherId;
|
||||||
private List<Core.Models.View.CollectionView> _writeableCollections;
|
private List<Core.Models.View.CollectionView> _writeableCollections;
|
||||||
private string[] _additionalCipherProperties = new string[]
|
private string[] _additionalCipherProperties = new string[]
|
||||||
{
|
{
|
||||||
@@ -74,6 +76,7 @@ namespace Bit.App.Pages
|
|||||||
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||||
_collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
_collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
||||||
|
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
GeneratePasswordCommand = new Command(GeneratePassword);
|
GeneratePasswordCommand = new Command(GeneratePassword);
|
||||||
TogglePasswordCommand = new Command(TogglePassword);
|
TogglePasswordCommand = new Command(TogglePassword);
|
||||||
ToggleCardCodeCommand = new Command(ToggleCardCode);
|
ToggleCardCodeCommand = new Command(ToggleCardCode);
|
||||||
@@ -365,9 +368,16 @@ namespace Bit.App.Pages
|
|||||||
}
|
}
|
||||||
if(Cipher.Fields != null)
|
if(Cipher.Fields != null)
|
||||||
{
|
{
|
||||||
Fields.ResetWithRange(Cipher.Fields?.Select(f => new AddEditPageFieldViewModel(f)));
|
Fields.ResetWithRange(Cipher.Fields?.Select(f => new AddEditPageFieldViewModel(Cipher, f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(EditMode && _previousCipherId != CipherId)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(EventType.Cipher_ClientViewed, CipherId);
|
||||||
|
}
|
||||||
|
_previousCipherId = CipherId;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,7 +601,7 @@ namespace Bit.App.Pages
|
|||||||
Fields = new ExtendedObservableCollection<AddEditPageFieldViewModel>();
|
Fields = new ExtendedObservableCollection<AddEditPageFieldViewModel>();
|
||||||
}
|
}
|
||||||
var type = _fieldTypeOptions.FirstOrDefault(f => f.Value == typeSelection).Key;
|
var type = _fieldTypeOptions.FirstOrDefault(f => f.Value == typeSelection).Key;
|
||||||
Fields.Add(new AddEditPageFieldViewModel(new FieldView
|
Fields.Add(new AddEditPageFieldViewModel(Cipher, new FieldView
|
||||||
{
|
{
|
||||||
Type = type,
|
Type = type,
|
||||||
Name = string.IsNullOrWhiteSpace(name) ? null : name
|
Name = string.IsNullOrWhiteSpace(name) ? null : name
|
||||||
@@ -602,11 +612,19 @@ namespace Bit.App.Pages
|
|||||||
public void TogglePassword()
|
public void TogglePassword()
|
||||||
{
|
{
|
||||||
ShowPassword = !ShowPassword;
|
ShowPassword = !ShowPassword;
|
||||||
|
if(EditMode && ShowPassword)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(EventType.Cipher_ClientToggledPasswordVisible, CipherId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleCardCode()
|
public void ToggleCardCode()
|
||||||
{
|
{
|
||||||
ShowCardCode = !ShowCardCode;
|
ShowCardCode = !ShowCardCode;
|
||||||
|
if(EditMode && ShowCardCode)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(EventType.Cipher_ClientToggledCardCodeVisible, CipherId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateTotpKeyAsync(string key)
|
public async Task UpdateTotpKeyAsync(string key)
|
||||||
@@ -720,6 +738,7 @@ namespace Bit.App.Pages
|
|||||||
public class AddEditPageFieldViewModel : ExtendedViewModel
|
public class AddEditPageFieldViewModel : ExtendedViewModel
|
||||||
{
|
{
|
||||||
private FieldView _field;
|
private FieldView _field;
|
||||||
|
private CipherView _cipher;
|
||||||
private bool _showHiddenValue;
|
private bool _showHiddenValue;
|
||||||
private bool _booleanValue;
|
private bool _booleanValue;
|
||||||
private string[] _additionalFieldProperties = new string[]
|
private string[] _additionalFieldProperties = new string[]
|
||||||
@@ -729,8 +748,9 @@ namespace Bit.App.Pages
|
|||||||
nameof(IsTextType),
|
nameof(IsTextType),
|
||||||
};
|
};
|
||||||
|
|
||||||
public AddEditPageFieldViewModel(FieldView field)
|
public AddEditPageFieldViewModel(CipherView cipher, FieldView field)
|
||||||
{
|
{
|
||||||
|
_cipher = cipher;
|
||||||
Field = field;
|
Field = field;
|
||||||
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
||||||
BooleanValue = IsBooleanType && field.Value == "true";
|
BooleanValue = IsBooleanType && field.Value == "true";
|
||||||
@@ -775,6 +795,11 @@ namespace Bit.App.Pages
|
|||||||
public void ToggleHiddenValue()
|
public void ToggleHiddenValue()
|
||||||
{
|
{
|
||||||
ShowHiddenValue = !ShowHiddenValue;
|
ShowHiddenValue = !ShowHiddenValue;
|
||||||
|
if(ShowHiddenValue && _cipher?.Id != null)
|
||||||
|
{
|
||||||
|
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
|
var task = eventService.CollectAsync(EventType.Cipher_ClientToggledHiddenFieldVisible, _cipher.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerFieldChanged()
|
public void TriggerFieldChanged()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace Bit.App.Pages
|
|||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
private readonly IAuditService _auditService;
|
private readonly IAuditService _auditService;
|
||||||
private readonly IMessagingService _messagingService;
|
private readonly IMessagingService _messagingService;
|
||||||
|
private readonly IEventService _eventService;
|
||||||
private CipherView _cipher;
|
private CipherView _cipher;
|
||||||
private List<ViewPageFieldViewModel> _fields;
|
private List<ViewPageFieldViewModel> _fields;
|
||||||
private bool _canAccessPremium;
|
private bool _canAccessPremium;
|
||||||
@@ -32,6 +33,7 @@ namespace Bit.App.Pages
|
|||||||
private string _totpSec;
|
private string _totpSec;
|
||||||
private bool _totpLow;
|
private bool _totpLow;
|
||||||
private DateTime? _totpInterval = null;
|
private DateTime? _totpInterval = null;
|
||||||
|
private string _previousCipherId;
|
||||||
|
|
||||||
public ViewPageViewModel()
|
public ViewPageViewModel()
|
||||||
{
|
{
|
||||||
@@ -42,6 +44,7 @@ namespace Bit.App.Pages
|
|||||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||||
|
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
CopyCommand = new Command<string>((id) => CopyAsync(id, null));
|
CopyCommand = new Command<string>((id) => CopyAsync(id, null));
|
||||||
CopyUriCommand = new Command<LoginUriView>(CopyUri);
|
CopyUriCommand = new Command<LoginUriView>(CopyUri);
|
||||||
CopyFieldCommand = new Command<FieldView>(CopyField);
|
CopyFieldCommand = new Command<FieldView>(CopyField);
|
||||||
@@ -217,7 +220,7 @@ namespace Bit.App.Pages
|
|||||||
}
|
}
|
||||||
Cipher = await cipher.DecryptAsync();
|
Cipher = await cipher.DecryptAsync();
|
||||||
CanAccessPremium = await _userService.CanAccessPremiumAsync();
|
CanAccessPremium = await _userService.CanAccessPremiumAsync();
|
||||||
Fields = Cipher.Fields?.Select(f => new ViewPageFieldViewModel(f)).ToList();
|
Fields = Cipher.Fields?.Select(f => new ViewPageFieldViewModel(Cipher, f)).ToList();
|
||||||
|
|
||||||
if(Cipher.Type == Core.Enums.CipherType.Login && !string.IsNullOrWhiteSpace(Cipher.Login.Totp) &&
|
if(Cipher.Type == Core.Enums.CipherType.Login && !string.IsNullOrWhiteSpace(Cipher.Login.Totp) &&
|
||||||
(Cipher.OrganizationUseTotp || CanAccessPremium))
|
(Cipher.OrganizationUseTotp || CanAccessPremium))
|
||||||
@@ -236,6 +239,11 @@ namespace Bit.App.Pages
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(_previousCipherId != CipherId)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientViewed, CipherId);
|
||||||
|
}
|
||||||
|
_previousCipherId = CipherId;
|
||||||
finishedLoadingAction?.Invoke();
|
finishedLoadingAction?.Invoke();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -248,11 +256,20 @@ namespace Bit.App.Pages
|
|||||||
public void TogglePassword()
|
public void TogglePassword()
|
||||||
{
|
{
|
||||||
ShowPassword = !ShowPassword;
|
ShowPassword = !ShowPassword;
|
||||||
|
if(ShowPassword)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientToggledPasswordVisible, CipherId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleCardCode()
|
public void ToggleCardCode()
|
||||||
{
|
{
|
||||||
ShowCardCode = !ShowCardCode;
|
ShowCardCode = !ShowCardCode;
|
||||||
|
if(ShowCardCode)
|
||||||
|
{
|
||||||
|
var task = _eventService.CollectAsync(
|
||||||
|
Core.Enums.EventType.Cipher_ClientToggledCardCodeVisible, CipherId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> DeleteAsync()
|
public async Task<bool> DeleteAsync()
|
||||||
@@ -434,7 +451,7 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
name = AppResources.URI;
|
name = AppResources.URI;
|
||||||
}
|
}
|
||||||
else if(id == "FieldValue")
|
else if(id == "FieldValue" || id == "H_FieldValue")
|
||||||
{
|
{
|
||||||
name = AppResources.Value;
|
name = AppResources.Value;
|
||||||
}
|
}
|
||||||
@@ -456,6 +473,18 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
_platformUtilsService.ShowToast("info", null, string.Format(AppResources.ValueHasBeenCopied, name));
|
_platformUtilsService.ShowToast("info", null, string.Format(AppResources.ValueHasBeenCopied, name));
|
||||||
}
|
}
|
||||||
|
if(id == "LoginPassword")
|
||||||
|
{
|
||||||
|
await _eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedPassword, CipherId);
|
||||||
|
}
|
||||||
|
else if(id == "CardCode")
|
||||||
|
{
|
||||||
|
await _eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedCardCode, CipherId);
|
||||||
|
}
|
||||||
|
else if(id == "H_FieldValue")
|
||||||
|
{
|
||||||
|
await _eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedHiddenField, CipherId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +495,7 @@ namespace Bit.App.Pages
|
|||||||
|
|
||||||
private void CopyField(FieldView field)
|
private void CopyField(FieldView field)
|
||||||
{
|
{
|
||||||
CopyAsync("FieldValue", field.Value);
|
CopyAsync(field.Type == Core.Enums.FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LaunchUri(LoginUriView uri)
|
private void LaunchUri(LoginUriView uri)
|
||||||
@@ -481,10 +510,12 @@ namespace Bit.App.Pages
|
|||||||
public class ViewPageFieldViewModel : ExtendedViewModel
|
public class ViewPageFieldViewModel : ExtendedViewModel
|
||||||
{
|
{
|
||||||
private FieldView _field;
|
private FieldView _field;
|
||||||
|
private CipherView _cipher;
|
||||||
private bool _showHiddenValue;
|
private bool _showHiddenValue;
|
||||||
|
|
||||||
public ViewPageFieldViewModel(FieldView field)
|
public ViewPageFieldViewModel(CipherView cipher, FieldView field)
|
||||||
{
|
{
|
||||||
|
_cipher = cipher;
|
||||||
Field = field;
|
Field = field;
|
||||||
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
||||||
}
|
}
|
||||||
@@ -526,6 +557,12 @@ namespace Bit.App.Pages
|
|||||||
public void ToggleHiddenValue()
|
public void ToggleHiddenValue()
|
||||||
{
|
{
|
||||||
ShowHiddenValue = !ShowHiddenValue;
|
ShowHiddenValue = !ShowHiddenValue;
|
||||||
|
if(ShowHiddenValue)
|
||||||
|
{
|
||||||
|
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
|
var task = eventService.CollectAsync(
|
||||||
|
Core.Enums.EventType.Cipher_ClientToggledHiddenFieldVisible, _cipher.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Bit.App.Utilities
|
|||||||
public static async Task<string> CipherListOptions(ContentPage page, CipherView cipher)
|
public static async Task<string> CipherListOptions(ContentPage page, CipherView cipher)
|
||||||
{
|
{
|
||||||
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
|
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||||
var options = new List<string> { AppResources.View, AppResources.Edit };
|
var options = new List<string> { AppResources.View, AppResources.Edit };
|
||||||
if(cipher.Type == Core.Enums.CipherType.Login)
|
if(cipher.Type == Core.Enums.CipherType.Login)
|
||||||
{
|
{
|
||||||
@@ -79,6 +80,7 @@ namespace Bit.App.Utilities
|
|||||||
await platformUtilsService.CopyToClipboardAsync(cipher.Login.Password);
|
await platformUtilsService.CopyToClipboardAsync(cipher.Login.Password);
|
||||||
platformUtilsService.ShowToast("info", null,
|
platformUtilsService.ShowToast("info", null,
|
||||||
string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
||||||
|
var task = eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedPassword, cipher.Id);
|
||||||
}
|
}
|
||||||
else if(selection == AppResources.CopyTotp)
|
else if(selection == AppResources.CopyTotp)
|
||||||
{
|
{
|
||||||
@@ -106,6 +108,7 @@ namespace Bit.App.Utilities
|
|||||||
await platformUtilsService.CopyToClipboardAsync(cipher.Card.Code);
|
await platformUtilsService.CopyToClipboardAsync(cipher.Card.Code);
|
||||||
platformUtilsService.ShowToast("info", null,
|
platformUtilsService.ShowToast("info", null,
|
||||||
string.Format(AppResources.ValueHasBeenCopied, AppResources.SecurityCode));
|
string.Format(AppResources.ValueHasBeenCopied, AppResources.SecurityCode));
|
||||||
|
var task = eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedCardCode, cipher.Id);
|
||||||
}
|
}
|
||||||
else if(selection == AppResources.CopyNotes)
|
else if(selection == AppResources.CopyNotes)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,5 +43,6 @@
|
|||||||
|
|
||||||
Organization_Updated = 1600,
|
Organization_Updated = 1600,
|
||||||
Organization_PurgedVault = 1601,
|
Organization_PurgedVault = 1601,
|
||||||
|
// Organization_ClientExportedVault = 1602,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user