2019-05-10 21:33:33 +03:00
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Bit.App.Resources;
|
|
|
|
|
using Bit.Core.Abstractions;
|
|
|
|
|
using Bit.Core.Exceptions;
|
|
|
|
|
using Bit.Core.Models.Domain;
|
|
|
|
|
using Bit.Core.Models.View;
|
|
|
|
|
using Bit.Core.Utilities;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
2019-05-11 06:43:35 +03:00
|
|
|
|
using Xamarin.Forms;
|
2019-05-10 21:33:33 +03:00
|
|
|
|
|
|
|
|
|
namespace Bit.App.Pages
|
|
|
|
|
{
|
|
|
|
|
public class AttachmentsPageViewModel : BaseViewModel
|
|
|
|
|
{
|
|
|
|
|
private readonly IDeviceActionService _deviceActionService;
|
|
|
|
|
private readonly ICipherService _cipherService;
|
2019-05-11 06:43:35 +03:00
|
|
|
|
private readonly ICryptoService _cryptoService;
|
|
|
|
|
private readonly IUserService _userService;
|
2019-05-10 21:33:33 +03:00
|
|
|
|
private readonly IPlatformUtilsService _platformUtilsService;
|
|
|
|
|
private CipherView _cipher;
|
|
|
|
|
private Cipher _cipherDomain;
|
2019-05-11 06:43:35 +03:00
|
|
|
|
private bool _hasAttachments;
|
|
|
|
|
private bool _hasUpdatedKey;
|
|
|
|
|
private bool _canAccessAttachments;
|
|
|
|
|
private string _fileName;
|
2019-05-10 21:33:33 +03:00
|
|
|
|
|
|
|
|
|
public AttachmentsPageViewModel()
|
|
|
|
|
{
|
|
|
|
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
|
|
|
|
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
2019-05-11 06:43:35 +03:00
|
|
|
|
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
2019-05-10 21:33:33 +03:00
|
|
|
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
2019-05-11 06:43:35 +03:00
|
|
|
|
_userService = ServiceContainer.Resolve<IUserService>("userService");
|
|
|
|
|
Attachments = new ExtendedObservableCollection<AttachmentView>();
|
|
|
|
|
DeleteAttachmentCommand = new Command<AttachmentView>(DeleteAsync);
|
|
|
|
|
PageTitle = AppResources.Attachments;
|
2019-05-10 21:33:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string CipherId { get; set; }
|
2019-05-11 06:43:35 +03:00
|
|
|
|
public CipherView Cipher
|
2019-05-10 21:33:33 +03:00
|
|
|
|
{
|
2019-05-11 06:43:35 +03:00
|
|
|
|
get => _cipher;
|
|
|
|
|
set => SetProperty(ref _cipher, value);
|
2019-05-10 21:33:33 +03:00
|
|
|
|
}
|
2019-05-11 06:43:35 +03:00
|
|
|
|
public ExtendedObservableCollection<AttachmentView> Attachments { get; set; }
|
|
|
|
|
public bool HasAttachments
|
|
|
|
|
{
|
|
|
|
|
get => _hasAttachments;
|
|
|
|
|
set => SetProperty(ref _hasAttachments, value);
|
|
|
|
|
}
|
|
|
|
|
public string FileName
|
|
|
|
|
{
|
|
|
|
|
get => _fileName;
|
|
|
|
|
set => SetProperty(ref _fileName, value);
|
|
|
|
|
}
|
|
|
|
|
public byte[] FileData { get; set; }
|
|
|
|
|
public Command DeleteAttachmentCommand { get; set; }
|
2019-05-10 21:33:33 +03:00
|
|
|
|
|
2019-05-11 06:43:35 +03:00
|
|
|
|
public async Task InitAsync()
|
2019-05-10 21:33:33 +03:00
|
|
|
|
{
|
|
|
|
|
_cipherDomain = await _cipherService.GetAsync(CipherId);
|
2019-05-11 06:43:35 +03:00
|
|
|
|
Cipher = await _cipherDomain.DecryptAsync();
|
|
|
|
|
LoadAttachments();
|
|
|
|
|
_hasUpdatedKey = await _cryptoService.HasEncKeyAsync();
|
|
|
|
|
var canAccessPremium = await _userService.CanAccessPremiumAsync();
|
|
|
|
|
_canAccessAttachments = canAccessPremium || Cipher.OrganizationId != null;
|
|
|
|
|
if(!_canAccessAttachments)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(AppResources.PremiumRequired);
|
|
|
|
|
}
|
|
|
|
|
else if(!_hasUpdatedKey)
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.UpdateKey,
|
|
|
|
|
AppResources.FeatureUnavailable, AppResources.LearnMore, AppResources.Cancel);
|
|
|
|
|
if(confirmed)
|
2019-05-10 21:33:33 +03:00
|
|
|
|
{
|
2019-05-11 06:43:35 +03:00
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/update-encryption-key/");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-10 21:33:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<bool> SubmitAsync()
|
|
|
|
|
{
|
2019-06-04 05:43:52 +03:00
|
|
|
|
if(Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
|
|
|
|
|
AppResources.InternetConnectionRequiredTitle);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-05-11 06:43:35 +03:00
|
|
|
|
if(!_hasUpdatedKey)
|
2019-05-10 21:33:33 +03:00
|
|
|
|
{
|
2019-05-11 06:43:35 +03:00
|
|
|
|
await _platformUtilsService.ShowDialogAsync(AppResources.UpdateKey,
|
|
|
|
|
AppResources.AnErrorHasOccurred);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(FileData == null)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(
|
|
|
|
|
string.Format(AppResources.ValidationFieldRequired, AppResources.File),
|
|
|
|
|
AppResources.AnErrorHasOccurred);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(FileData.Length > 104857600) // 100 MB
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(AppResources.MaxFileSize,
|
|
|
|
|
AppResources.AnErrorHasOccurred);
|
2019-05-10 21:33:33 +03:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
2019-05-11 06:43:35 +03:00
|
|
|
|
_cipherDomain = await _cipherService.SaveAttachmentRawWithServerAsync(
|
|
|
|
|
_cipherDomain, FileName, FileData);
|
|
|
|
|
Cipher = await _cipherDomain.DecryptAsync();
|
2019-05-10 21:33:33 +03:00
|
|
|
|
await _deviceActionService.HideLoadingAsync();
|
2019-05-11 06:43:35 +03:00
|
|
|
|
_platformUtilsService.ShowToast("success", null, AppResources.AttachementAdded);
|
|
|
|
|
LoadAttachments();
|
|
|
|
|
FileData = null;
|
|
|
|
|
FileName = null;
|
2019-05-10 21:33:33 +03:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(ApiException e)
|
|
|
|
|
{
|
|
|
|
|
await _deviceActionService.HideLoadingAsync();
|
2019-10-22 23:37:40 +03:00
|
|
|
|
if(e?.Error != null)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(e.Error.GetSingleMessage(),
|
|
|
|
|
AppResources.AnErrorHasOccurred);
|
|
|
|
|
}
|
2019-05-10 21:33:33 +03:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-05-11 06:43:35 +03:00
|
|
|
|
|
|
|
|
|
public async Task ChooseFileAsync()
|
|
|
|
|
{
|
|
|
|
|
await _deviceActionService.SelectFileAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void DeleteAsync(AttachmentView attachment)
|
|
|
|
|
{
|
2019-06-04 05:43:52 +03:00
|
|
|
|
if(Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
|
|
|
|
|
AppResources.InternetConnectionRequiredTitle);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-11 06:43:35 +03:00
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.DoYouReallyWantToDelete,
|
|
|
|
|
null, AppResources.Yes, AppResources.No);
|
|
|
|
|
if(!confirmed)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _deviceActionService.ShowLoadingAsync(AppResources.Deleting);
|
|
|
|
|
await _cipherService.DeleteAttachmentWithServerAsync(Cipher.Id, attachment.Id);
|
|
|
|
|
await _deviceActionService.HideLoadingAsync();
|
|
|
|
|
_platformUtilsService.ShowToast("success", null, AppResources.AttachmentDeleted);
|
|
|
|
|
var attachmentToRemove = Cipher.Attachments.FirstOrDefault(a => a.Id == attachment.Id);
|
|
|
|
|
if(attachmentToRemove != null)
|
|
|
|
|
{
|
|
|
|
|
Cipher.Attachments.Remove(attachmentToRemove);
|
|
|
|
|
LoadAttachments();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(ApiException e)
|
|
|
|
|
{
|
|
|
|
|
await _deviceActionService.HideLoadingAsync();
|
2019-10-22 23:37:40 +03:00
|
|
|
|
if(e?.Error != null)
|
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.ShowDialogAsync(e.Error.GetSingleMessage(),
|
|
|
|
|
AppResources.AnErrorHasOccurred);
|
|
|
|
|
}
|
2019-05-11 06:43:35 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoadAttachments()
|
|
|
|
|
{
|
|
|
|
|
Attachments.ResetWithRange(Cipher.Attachments ?? new List<AttachmentView>());
|
|
|
|
|
HasAttachments = Cipher.HasAttachments;
|
|
|
|
|
}
|
2019-05-10 21:33:33 +03:00
|
|
|
|
}
|
|
|
|
|
}
|