mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-27 12:26:31 +01:00
refactoring code for login => cipher support
This commit is contained in:
parent
37f05f0a12
commit
1d6ec0f953
@ -195,7 +195,7 @@ namespace Bit.Android
|
||||
container.RegisterSingleton<IKeyDerivationService, BouncyCastleKeyDerivationService>();
|
||||
container.RegisterSingleton<IAuthService, AuthService>();
|
||||
container.RegisterSingleton<IFolderService, FolderService>();
|
||||
container.RegisterSingleton<ILoginService, LoginService>();
|
||||
container.RegisterSingleton<ICipherService, CipherService>();
|
||||
container.RegisterSingleton<ISyncService, SyncService>();
|
||||
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
|
||||
container.RegisterSingleton<IAppIdService, AppIdService>();
|
||||
@ -216,7 +216,7 @@ namespace Bit.Android
|
||||
// Repositories
|
||||
container.RegisterSingleton<IFolderRepository, FolderRepository>();
|
||||
container.RegisterSingleton<IFolderApiRepository, FolderApiRepository>();
|
||||
container.RegisterSingleton<ILoginRepository, LoginRepository>();
|
||||
container.RegisterSingleton<ICipherRepository, CipherRepository>();
|
||||
container.RegisterSingleton<IAttachmentRepository, AttachmentRepository>();
|
||||
container.RegisterSingleton<IConnectApiRepository, ConnectApiRepository>();
|
||||
container.RegisterSingleton<IDeviceApiRepository, DeviceApiRepository>();
|
||||
|
@ -7,7 +7,7 @@ namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IAttachmentRepository : IRepository<AttachmentData, string>
|
||||
{
|
||||
Task<IEnumerable<AttachmentData>> GetAllByLoginIdAsync(string loginId);
|
||||
Task<IEnumerable<AttachmentData>> GetAllByCipherIdAsync(string cipherId);
|
||||
Task<IEnumerable<AttachmentData>> GetAllByUserIdAsync(string userId);
|
||||
}
|
||||
}
|
||||
|
13
src/App/Abstractions/Repositories/ICipherRepository.cs
Normal file
13
src/App/Abstractions/Repositories/ICipherRepository.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ICipherRepository : IRepository<CipherData, string>
|
||||
{
|
||||
Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId);
|
||||
Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId, bool favorite);
|
||||
}
|
||||
}
|
@ -8,6 +8,6 @@ namespace Bit.App.Abstractions
|
||||
public interface IFolderRepository : IRepository<FolderData, string>
|
||||
{
|
||||
Task<IEnumerable<FolderData>> GetAllByUserIdAsync(string userId);
|
||||
Task DeleteWithLoginUpdateAsync(string id, DateTime revisionDate);
|
||||
Task DeleteWithCipherUpdateAsync(string id, DateTime revisionDate);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ILoginRepository : IRepository<LoginData, string>
|
||||
{
|
||||
Task<IEnumerable<LoginData>> GetAllByUserIdAsync(string userId);
|
||||
Task<IEnumerable<LoginData>> GetAllByUserIdAsync(string userId, bool favorite);
|
||||
}
|
||||
}
|
21
src/App/Abstractions/Services/ICipherService.cs
Normal file
21
src/App/Abstractions/Services/ICipherService.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models.Api;
|
||||
using System;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ICipherService
|
||||
{
|
||||
Task<Cipher> GetByIdAsync(string id);
|
||||
Task<IEnumerable<Cipher>> GetAllAsync();
|
||||
Task<IEnumerable<Cipher>> GetAllAsync(bool favorites);
|
||||
Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString);
|
||||
Task<ApiResult<CipherResponse>> SaveAsync(Cipher login);
|
||||
Task<ApiResult> DeleteAsync(string id);
|
||||
Task<byte[]> DownloadAndDecryptAttachmentAsync(string url, string orgId = null);
|
||||
Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Cipher login, byte[] data, string fileName);
|
||||
Task<ApiResult> DeleteAttachmentAsync(Cipher login, string attachmentId);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models.Api;
|
||||
using System;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ILoginService
|
||||
{
|
||||
Task<Login> GetByIdAsync(string id);
|
||||
Task<IEnumerable<Login>> GetAllAsync();
|
||||
Task<IEnumerable<Login>> GetAllAsync(bool favorites);
|
||||
Task<Tuple<IEnumerable<Login>, IEnumerable<Login>>> GetAllAsync(string uriString);
|
||||
Task<ApiResult<CipherResponse>> SaveAsync(Login login);
|
||||
Task<ApiResult> DeleteAsync(string id);
|
||||
Task<byte[]> DownloadAndDecryptAttachmentAsync(string url, string orgId = null);
|
||||
Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Login login, byte[] data, string fileName);
|
||||
Task<ApiResult> DeleteAttachmentAsync(Login login, string attachmentId);
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ namespace Bit.App.Abstractions
|
||||
Task<bool> SyncCipherAsync(string id);
|
||||
Task<bool> SyncFolderAsync(string id);
|
||||
Task<bool> SyncDeleteFolderAsync(string id, DateTime revisionDate);
|
||||
Task<bool> SyncDeleteLoginAsync(string id);
|
||||
Task<bool> SyncDeleteCipherAsync(string id);
|
||||
Task<bool> SyncSettingsAsync();
|
||||
Task<bool> SyncProfileAsync();
|
||||
Task<bool> FullSyncAsync(bool forceSync = false);
|
||||
|
@ -58,7 +58,7 @@
|
||||
<Compile Include="Abstractions\Services\IKeyDerivationService.cs" />
|
||||
<Compile Include="Abstractions\Services\ILogService.cs" />
|
||||
<Compile Include="Abstractions\Services\IReflectionService.cs" />
|
||||
<Compile Include="Abstractions\Services\ILoginService.cs" />
|
||||
<Compile Include="Abstractions\Services\ICipherService.cs" />
|
||||
<Compile Include="Abstractions\Services\IFolderService.cs" />
|
||||
<Compile Include="App.cs" />
|
||||
<Compile Include="Abstractions\Services\ISecureStorageService.cs" />
|
||||
@ -91,6 +91,7 @@
|
||||
<Compile Include="Controls\VaultListViewCell.cs" />
|
||||
<Compile Include="Enums\DeviceType.cs" />
|
||||
<Compile Include="Enums\FieldType.cs" />
|
||||
<Compile Include="Enums\SecureNoteType.cs" />
|
||||
<Compile Include="Enums\TwoFactorProviderType.cs" />
|
||||
<Compile Include="Enums\EncryptionType.cs" />
|
||||
<Compile Include="Enums\OrganizationUserType.cs" />
|
||||
@ -104,6 +105,9 @@
|
||||
<Compile Include="Models\Api\ApiResult.cs" />
|
||||
<Compile Include="Models\Api\CipherDataModel.cs" />
|
||||
<Compile Include="Models\Api\FieldDataModel.cs" />
|
||||
<Compile Include="Models\Api\CardDataModel.cs" />
|
||||
<Compile Include="Models\Api\IdentityDataModel.cs" />
|
||||
<Compile Include="Models\Api\SecureNoteDataModel.cs" />
|
||||
<Compile Include="Models\Api\Request\DeviceTokenRequest.cs" />
|
||||
<Compile Include="Models\Api\Request\FolderRequest.cs" />
|
||||
<Compile Include="Models\Api\Request\DeviceRequest.cs" />
|
||||
@ -125,16 +129,20 @@
|
||||
<Compile Include="Models\Api\Response\TokenResponse.cs" />
|
||||
<Compile Include="Models\Api\Response\ProfileResponse.cs" />
|
||||
<Compile Include="Models\Api\LoginDataModel.cs" />
|
||||
<Compile Include="Models\Card.cs" />
|
||||
<Compile Include="Models\CipherString.cs" />
|
||||
<Compile Include="Models\Data\AttachmentData.cs" />
|
||||
<Compile Include="Models\Attachment.cs" />
|
||||
<Compile Include="Models\Field.cs" />
|
||||
<Compile Include="Models\Identity.cs" />
|
||||
<Compile Include="Models\Login.cs" />
|
||||
<Compile Include="Models\Page\VaultAttachmentsPageModel.cs" />
|
||||
<Compile Include="Models\SecureNote.cs" />
|
||||
<Compile Include="Models\SymmetricCryptoKey.cs" />
|
||||
<Compile Include="Models\Data\SettingsData.cs" />
|
||||
<Compile Include="Models\Data\FolderData.cs" />
|
||||
<Compile Include="Abstractions\IDataObject.cs" />
|
||||
<Compile Include="Models\Data\LoginData.cs" />
|
||||
<Compile Include="Models\Data\CipherData.cs" />
|
||||
<Compile Include="Models\DomainName.cs" />
|
||||
<Compile Include="Models\Folder.cs" />
|
||||
<Compile Include="Models\LoginResult.cs" />
|
||||
@ -144,7 +152,7 @@
|
||||
<Compile Include="Models\Page\PasswordGeneratorPageModel.cs" />
|
||||
<Compile Include="Models\PlatformCulture.cs" />
|
||||
<Compile Include="Models\PushNotification.cs" />
|
||||
<Compile Include="Models\Login.cs" />
|
||||
<Compile Include="Models\Cipher.cs" />
|
||||
<Compile Include="Models\Page\VaultViewLoginPageModel.cs" />
|
||||
<Compile Include="Pages\HomePage.cs" />
|
||||
<Compile Include="Pages\Lock\BaseLockPage.cs" />
|
||||
@ -175,7 +183,7 @@
|
||||
<Compile Include="Pages\Vault\VaultAutofillListLoginsPage.cs" />
|
||||
<Compile Include="Pages\Vault\VaultAttachmentsPage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Abstractions\Repositories\ILoginRepository.cs" />
|
||||
<Compile Include="Abstractions\Repositories\ICipherRepository.cs" />
|
||||
<Compile Include="Repositories\AttachmentRepository.cs" />
|
||||
<Compile Include="Repositories\SyncApiRepository.cs" />
|
||||
<Compile Include="Repositories\TwoFactorApiRepository.cs" />
|
||||
@ -192,7 +200,7 @@
|
||||
<Compile Include="Abstractions\Repositories\ICipherApiRepository.cs" />
|
||||
<Compile Include="Repositories\SettingsRepository.cs" />
|
||||
<Compile Include="Repositories\FolderApiRepository.cs" />
|
||||
<Compile Include="Repositories\LoginRepository.cs" />
|
||||
<Compile Include="Repositories\CipherRepository.cs" />
|
||||
<Compile Include="Repositories\FolderRepository.cs" />
|
||||
<Compile Include="Abstractions\Repositories\IFolderRepository.cs" />
|
||||
<Compile Include="Abstractions\Repositories\IRepository.cs" />
|
||||
@ -340,7 +348,7 @@
|
||||
<Compile Include="Abstractions\Services\ISyncService.cs" />
|
||||
<Compile Include="Abstractions\Services\IPasswordGenerationService.cs" />
|
||||
<Compile Include="Services\SyncService.cs" />
|
||||
<Compile Include="Services\LoginService.cs" />
|
||||
<Compile Include="Services\CipherService.cs" />
|
||||
<Compile Include="Services\AuthService.cs" />
|
||||
<Compile Include="Services\CryptoService.cs" />
|
||||
<Compile Include="Models\Page\VaultListPageModel.cs" />
|
||||
|
@ -6,6 +6,7 @@
|
||||
//Folder = 0,
|
||||
Login = 1,
|
||||
SecureNote = 2,
|
||||
Card = 3
|
||||
Card = 3,
|
||||
Identity = 4
|
||||
}
|
||||
}
|
||||
|
7
src/App/Enums/SecureNoteType.cs
Normal file
7
src/App/Enums/SecureNoteType.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Bit.App.Enums
|
||||
{
|
||||
public enum SecureNoteType : byte
|
||||
{
|
||||
Generic = 0
|
||||
}
|
||||
}
|
12
src/App/Models/Api/CardDataModel.cs
Normal file
12
src/App/Models/Api/CardDataModel.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Bit.App.Models.Api
|
||||
{
|
||||
public class CardDataModel : CipherDataModel
|
||||
{
|
||||
public string CardholderName { get; set; }
|
||||
public string Brand { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string ExpMonth { get; set; }
|
||||
public string ExpYear { get; set; }
|
||||
public string Code { get; set; }
|
||||
}
|
||||
}
|
24
src/App/Models/Api/IdentityDataModel.cs
Normal file
24
src/App/Models/Api/IdentityDataModel.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace Bit.App.Models.Api
|
||||
{
|
||||
public class IdentityDataModel : CipherDataModel
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string MiddleName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string Address1 { get; set; }
|
||||
public string Address2 { get; set; }
|
||||
public string Address3 { get; set; }
|
||||
public string City { get; set; }
|
||||
public string State { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string Company { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Phone { get; set; }
|
||||
public string SSN { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string PassportNumber { get; set; }
|
||||
public string LicenseNumber { get; set; }
|
||||
}
|
||||
}
|
@ -6,18 +6,18 @@ namespace Bit.App.Models.Api
|
||||
{
|
||||
public class CipherRequest
|
||||
{
|
||||
public CipherRequest(Login login)
|
||||
public CipherRequest(Cipher cipher)
|
||||
{
|
||||
Type = CipherType.Login;
|
||||
OrganizationId = login.OrganizationId;
|
||||
FolderId = login.FolderId;
|
||||
Name = login.Name?.EncryptedString;
|
||||
Notes = login.Notes?.EncryptedString;
|
||||
Favorite = login.Favorite;
|
||||
Type = cipher.Type;
|
||||
OrganizationId = cipher.OrganizationId;
|
||||
FolderId = cipher.FolderId;
|
||||
Name = cipher.Name?.EncryptedString;
|
||||
Notes = cipher.Notes?.EncryptedString;
|
||||
Favorite = cipher.Favorite;
|
||||
|
||||
if(login.Fields != null)
|
||||
if(cipher.Fields != null)
|
||||
{
|
||||
Fields = login.Fields.Select(f => new FieldDataModel
|
||||
Fields = cipher.Fields.Select(f => new FieldDataModel
|
||||
{
|
||||
Name = f.Name?.EncryptedString,
|
||||
Value = f.Value?.EncryptedString,
|
||||
@ -28,7 +28,16 @@ namespace Bit.App.Models.Api
|
||||
switch(Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
Login = new LoginType(login);
|
||||
Login = new LoginType(cipher);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
Card = new CardType(cipher);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
Identity = new IdentityType(cipher);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
SecureNote = new SecureNoteType(cipher);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -42,16 +51,20 @@ namespace Bit.App.Models.Api
|
||||
public string Name { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public IEnumerable<FieldDataModel> Fields { get; set; }
|
||||
|
||||
public LoginType Login { get; set; }
|
||||
public CardType Card { get; set; }
|
||||
public IdentityType Identity { get; set; }
|
||||
public SecureNoteType SecureNote { get; set; }
|
||||
|
||||
public class LoginType
|
||||
{
|
||||
public LoginType(Login login)
|
||||
public LoginType(Cipher cipher)
|
||||
{
|
||||
Uri = login.Uri?.EncryptedString;
|
||||
Username = login.Username?.EncryptedString;
|
||||
Password = login.Password?.EncryptedString;
|
||||
Totp = login.Totp?.EncryptedString;
|
||||
Uri = cipher.Login.Uri?.EncryptedString;
|
||||
Username = cipher.Login.Username?.EncryptedString;
|
||||
Password = cipher.Login.Password?.EncryptedString;
|
||||
Totp = cipher.Login.Totp?.EncryptedString;
|
||||
}
|
||||
|
||||
public string Uri { get; set; }
|
||||
@ -59,5 +72,79 @@ namespace Bit.App.Models.Api
|
||||
public string Password { get; set; }
|
||||
public string Totp { get; set; }
|
||||
}
|
||||
|
||||
public class CardType
|
||||
{
|
||||
public CardType(Cipher cipher)
|
||||
{
|
||||
CardholderName = cipher.Card.CardholderName?.EncryptedString;
|
||||
Brand = cipher.Card.Brand?.EncryptedString;
|
||||
Number = cipher.Card.Number?.EncryptedString;
|
||||
ExpMonth = cipher.Card.ExpMonth?.EncryptedString;
|
||||
ExpYear = cipher.Card.ExpYear?.EncryptedString;
|
||||
Code = cipher.Card.Code?.EncryptedString;
|
||||
}
|
||||
|
||||
public string CardholderName { get; set; }
|
||||
public string Brand { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string ExpMonth { get; set; }
|
||||
public string ExpYear { get; set; }
|
||||
public string Code { get; set; }
|
||||
}
|
||||
|
||||
public class IdentityType
|
||||
{
|
||||
public IdentityType(Cipher cipher)
|
||||
{
|
||||
Title = cipher.Identity.Title?.EncryptedString;
|
||||
FirstName = cipher.Identity.FirstName?.EncryptedString;
|
||||
MiddleName = cipher.Identity.MiddleName?.EncryptedString;
|
||||
LastName = cipher.Identity.LastName?.EncryptedString;
|
||||
Address1 = cipher.Identity.Address1?.EncryptedString;
|
||||
Address2 = cipher.Identity.Address2?.EncryptedString;
|
||||
Address3 = cipher.Identity.Address3?.EncryptedString;
|
||||
City = cipher.Identity.City?.EncryptedString;
|
||||
State = cipher.Identity.State?.EncryptedString;
|
||||
PostalCode = cipher.Identity.PostalCode?.EncryptedString;
|
||||
Country = cipher.Identity.Country?.EncryptedString;
|
||||
Company = cipher.Identity.Company?.EncryptedString;
|
||||
Email = cipher.Identity.Email?.EncryptedString;
|
||||
Phone = cipher.Identity.Phone?.EncryptedString;
|
||||
SSN = cipher.Identity.SSN?.EncryptedString;
|
||||
Username = cipher.Identity.Username?.EncryptedString;
|
||||
PassportNumber = cipher.Identity.PassportNumber?.EncryptedString;
|
||||
LicenseNumber = cipher.Identity.LicenseNumber?.EncryptedString;
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string MiddleName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string Address1 { get; set; }
|
||||
public string Address2 { get; set; }
|
||||
public string Address3 { get; set; }
|
||||
public string City { get; set; }
|
||||
public string State { get; set; }
|
||||
public string PostalCode { get; set; }
|
||||
public string Country { get; set; }
|
||||
public string Company { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Phone { get; set; }
|
||||
public string SSN { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string PassportNumber { get; set; }
|
||||
public string LicenseNumber { get; set; }
|
||||
}
|
||||
|
||||
public class SecureNoteType
|
||||
{
|
||||
public SecureNoteType(Cipher cipher)
|
||||
{
|
||||
Type = cipher.SecureNote.Type;
|
||||
}
|
||||
|
||||
public Enums.SecureNoteType Type { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
src/App/Models/Api/SecureNoteDataModel.cs
Normal file
9
src/App/Models/Api/SecureNoteDataModel.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Bit.App.Enums;
|
||||
|
||||
namespace Bit.App.Models.Api
|
||||
{
|
||||
public class SecureNoteDataModel : CipherDataModel
|
||||
{
|
||||
public SecureNoteType Type { get; set; }
|
||||
}
|
||||
}
|
29
src/App/Models/Card.cs
Normal file
29
src/App/Models/Card.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Bit.App.Models.Api;
|
||||
using Bit.App.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public class Card
|
||||
{
|
||||
public Card(CipherData data)
|
||||
{
|
||||
var deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Data);
|
||||
|
||||
CardholderName = deserializedData.CardholderName != null ?
|
||||
new CipherString(deserializedData.CardholderName) : null;
|
||||
Brand = deserializedData.Brand != null ? new CipherString(deserializedData.Brand) : null;
|
||||
Number = deserializedData.Number != null ? new CipherString(deserializedData.Number) : null;
|
||||
ExpMonth = deserializedData.ExpMonth != null ? new CipherString(deserializedData.ExpMonth) : null;
|
||||
ExpYear = deserializedData.ExpYear != null ? new CipherString(deserializedData.ExpYear) : null;
|
||||
Code = deserializedData.Code != null ? new CipherString(deserializedData.Code) : null;
|
||||
}
|
||||
|
||||
public CipherString CardholderName { get; set; }
|
||||
public CipherString Brand { get; set; }
|
||||
public CipherString Number { get; set; }
|
||||
public CipherString ExpMonth { get; set; }
|
||||
public CipherString ExpYear { get; set; }
|
||||
public CipherString Code { get; set; }
|
||||
}
|
||||
}
|
76
src/App/Models/Cipher.cs
Normal file
76
src/App/Models/Cipher.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using Bit.App.Enums;
|
||||
using Bit.App.Models.Api;
|
||||
using Bit.App.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public class Cipher
|
||||
{
|
||||
public Cipher()
|
||||
{ }
|
||||
|
||||
public Cipher(CipherData data, IEnumerable<AttachmentData> attachments = null)
|
||||
{
|
||||
Id = data.Id;
|
||||
UserId = data.UserId;
|
||||
OrganizationId = data.OrganizationId;
|
||||
FolderId = data.FolderId;
|
||||
Type = data.Type;
|
||||
Name = data.Name != null ? new CipherString(data.Name) : null;
|
||||
Notes = data.Notes != null ? new CipherString(data.Notes) : null;
|
||||
Favorite = data.Favorite;
|
||||
Edit = data.Edit;
|
||||
OrganizationUseTotp = data.OrganizationUseTotp;
|
||||
Attachments = attachments?.Select(a => new Attachment(a));
|
||||
|
||||
switch(Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
Login = new Login(data);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
SecureNote = new SecureNote(data);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
Card = new Card(data);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
Identity = new Identity(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(data.Fields))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fieldModels = JsonConvert.DeserializeObject<IEnumerable<FieldDataModel>>(data.Fields);
|
||||
Fields = fieldModels?.Select(f => new Field(f));
|
||||
}
|
||||
catch(JsonSerializationException) { }
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public CipherType Type { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public CipherString Notes { get; set; }
|
||||
public IEnumerable<Field> Fields { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public bool Edit { get; set; }
|
||||
public bool OrganizationUseTotp { get; set; }
|
||||
public IEnumerable<Attachment> Attachments { get; set; }
|
||||
|
||||
public Login Login { get; set; }
|
||||
public Identity Identity { get; set; }
|
||||
public Card Card { get; set; }
|
||||
public SecureNote SecureNote { get; set; }
|
||||
}
|
||||
}
|
@ -10,20 +10,20 @@ namespace Bit.App.Models.Data
|
||||
public AttachmentData()
|
||||
{ }
|
||||
|
||||
public AttachmentData(Attachment attachment, string loginId)
|
||||
public AttachmentData(Attachment attachment, string cipherId)
|
||||
{
|
||||
Id = attachment.Id;
|
||||
LoginId = loginId;
|
||||
LoginId = cipherId;
|
||||
Url = attachment.Url;
|
||||
FileName = attachment.FileName?.EncryptedString;
|
||||
Size = attachment.Size.ToString();
|
||||
SizeName = attachment.SizeName;
|
||||
}
|
||||
|
||||
public AttachmentData(AttachmentResponse response, string loginId)
|
||||
public AttachmentData(AttachmentResponse response, string cipherId)
|
||||
{
|
||||
Id = response.Id;
|
||||
LoginId = loginId;
|
||||
LoginId = cipherId;
|
||||
Url = response.Url;
|
||||
FileName = response.FileName;
|
||||
Size = response.Size;
|
||||
@ -32,6 +32,7 @@ namespace Bit.App.Models.Data
|
||||
|
||||
[PrimaryKey]
|
||||
public string Id { get; set; }
|
||||
// Really should be called CipherId
|
||||
[Indexed]
|
||||
public string LoginId { get; set; }
|
||||
public string Url { get; set; }
|
||||
|
100
src/App/Models/Data/CipherData.cs
Normal file
100
src/App/Models/Data/CipherData.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.Api;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
using Bit.App.Enums;
|
||||
|
||||
namespace Bit.App.Models.Data
|
||||
{
|
||||
// Old table that has just carried over for backward compat. sake. Should really be "Cipher"
|
||||
[Table("Site")]
|
||||
public class CipherData : IDataObject<string>
|
||||
{
|
||||
public CipherData()
|
||||
{ }
|
||||
|
||||
public CipherData(CipherResponse cipher, string userId)
|
||||
{
|
||||
Id = cipher.Id;
|
||||
FolderId = cipher.FolderId;
|
||||
UserId = userId;
|
||||
OrganizationId = cipher.OrganizationId;
|
||||
Favorite = cipher.Favorite;
|
||||
Edit = cipher.Edit;
|
||||
OrganizationUseTotp = cipher.OrganizationUseTotp;
|
||||
RevisionDateTime = cipher.RevisionDate;
|
||||
Type = cipher.Type;
|
||||
Data = JsonConvert.SerializeObject(cipher.Data);
|
||||
|
||||
CipherDataModel cipherData = null;
|
||||
switch(cipher.Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
var loginData = cipher.Data.ToObject<LoginDataModel>();
|
||||
cipherData = loginData;
|
||||
|
||||
Uri = loginData.Uri;
|
||||
Username = loginData.Username;
|
||||
Password = loginData.Password;
|
||||
Totp = loginData.Totp;
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
var noteData = cipher.Data.ToObject<SecureNoteDataModel>();
|
||||
cipherData = noteData;
|
||||
|
||||
SecureNoteType = noteData.Type;
|
||||
break;
|
||||
case CipherType.Card:
|
||||
var cardData = cipher.Data.ToObject<CardDataModel>();
|
||||
cipherData = cardData;
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
var idData = cipher.Data.ToObject<IdentityDataModel>();
|
||||
cipherData = idData;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(nameof(cipher.Type));
|
||||
}
|
||||
|
||||
Name = cipherData.Name;
|
||||
Notes = cipherData.Notes;
|
||||
|
||||
if(cipherData.Fields != null && cipherData.Fields.Any())
|
||||
{
|
||||
try
|
||||
{
|
||||
Fields = JsonConvert.SerializeObject(cipherData.Fields);
|
||||
}
|
||||
catch(JsonSerializationException) { }
|
||||
}
|
||||
}
|
||||
|
||||
[PrimaryKey]
|
||||
public string Id { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
[Indexed]
|
||||
public string UserId { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Fields { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public bool Edit { get; set; }
|
||||
public bool OrganizationUseTotp { get; set; }
|
||||
public DateTime RevisionDateTime { get; set; } = DateTime.UtcNow;
|
||||
[Indexed]
|
||||
public CipherType Type { get; set; } = CipherType.Login;
|
||||
public string Data { get; set; }
|
||||
|
||||
// Login metadata
|
||||
public string Uri { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Totp { get; set; }
|
||||
|
||||
// Secure Note metadata
|
||||
public SecureNoteType? SecureNoteType { get; set; }
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.Api;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.App.Models.Data
|
||||
{
|
||||
[Table("Site")]
|
||||
public class LoginData : IDataObject<string>
|
||||
{
|
||||
public LoginData()
|
||||
{ }
|
||||
|
||||
public LoginData(CipherResponse cipher, string userId)
|
||||
{
|
||||
if(cipher.Type != Enums.CipherType.Login)
|
||||
{
|
||||
throw new ArgumentException(nameof(cipher.Type));
|
||||
}
|
||||
|
||||
var data = cipher.Data.ToObject<LoginDataModel>();
|
||||
|
||||
Id = cipher.Id;
|
||||
FolderId = cipher.FolderId;
|
||||
UserId = userId;
|
||||
OrganizationId = cipher.OrganizationId;
|
||||
Name = data.Name;
|
||||
Uri = data.Uri;
|
||||
Username = data.Username;
|
||||
Password = data.Password;
|
||||
Notes = data.Notes;
|
||||
Totp = data.Totp;
|
||||
Favorite = cipher.Favorite;
|
||||
Edit = cipher.Edit;
|
||||
OrganizationUseTotp = cipher.OrganizationUseTotp;
|
||||
RevisionDateTime = cipher.RevisionDate;
|
||||
|
||||
if(data.Fields != null && data.Fields.Any())
|
||||
{
|
||||
try
|
||||
{
|
||||
Fields = JsonConvert.SerializeObject(data.Fields);
|
||||
}
|
||||
catch(JsonSerializationException) { }
|
||||
}
|
||||
}
|
||||
|
||||
[PrimaryKey]
|
||||
public string Id { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
[Indexed]
|
||||
public string UserId { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Totp { get; set; }
|
||||
public string Fields { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public bool Edit { get; set; }
|
||||
public bool OrganizationUseTotp { get; set; }
|
||||
public DateTime RevisionDateTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public Login ToLogin()
|
||||
{
|
||||
return new Login(this);
|
||||
}
|
||||
}
|
||||
}
|
54
src/App/Models/Identity.cs
Normal file
54
src/App/Models/Identity.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using Bit.App.Models.Api;
|
||||
using Bit.App.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public class Identity
|
||||
{
|
||||
public Identity(CipherData data)
|
||||
{
|
||||
var deserializedData = JsonConvert.DeserializeObject<IdentityDataModel>(data.Data);
|
||||
|
||||
Title = deserializedData.Title != null ? new CipherString(deserializedData.Title) : null;
|
||||
FirstName = deserializedData.FirstName != null ? new CipherString(deserializedData.FirstName) : null;
|
||||
MiddleName = deserializedData.MiddleName != null ? new CipherString(deserializedData.MiddleName) : null;
|
||||
LastName = deserializedData.LastName != null ? new CipherString(deserializedData.LastName) : null;
|
||||
Address1 = deserializedData.Address1 != null ? new CipherString(deserializedData.Address1) : null;
|
||||
Address2 = deserializedData.Address2 != null ? new CipherString(deserializedData.Address2) : null;
|
||||
Address3 = deserializedData.Address3 != null ? new CipherString(deserializedData.Address3) : null;
|
||||
City = deserializedData.City != null ? new CipherString(deserializedData.City) : null;
|
||||
State = deserializedData.State != null ? new CipherString(deserializedData.State) : null;
|
||||
PostalCode = deserializedData.PostalCode != null ? new CipherString(deserializedData.PostalCode) : null;
|
||||
Country = deserializedData.Country != null ? new CipherString(deserializedData.Country) : null;
|
||||
Company = deserializedData.Company != null ? new CipherString(deserializedData.Company) : null;
|
||||
Email = deserializedData.Email != null ? new CipherString(deserializedData.Email) : null;
|
||||
Phone = deserializedData.Phone != null ? new CipherString(deserializedData.Phone) : null;
|
||||
SSN = deserializedData.SSN != null ? new CipherString(deserializedData.SSN) : null;
|
||||
Username = deserializedData.Username != null ? new CipherString(deserializedData.Username) : null;
|
||||
PassportNumber = deserializedData.PassportNumber != null ?
|
||||
new CipherString(deserializedData.PassportNumber) : null;
|
||||
LicenseNumber = deserializedData.LicenseNumber != null ?
|
||||
new CipherString(deserializedData.LicenseNumber) : null;
|
||||
}
|
||||
|
||||
public CipherString Title { get; set; }
|
||||
public CipherString FirstName { get; set; }
|
||||
public CipherString MiddleName { get; set; }
|
||||
public CipherString LastName { get; set; }
|
||||
public CipherString Address1 { get; set; }
|
||||
public CipherString Address2 { get; set; }
|
||||
public CipherString Address3 { get; set; }
|
||||
public CipherString City { get; set; }
|
||||
public CipherString State { get; set; }
|
||||
public CipherString PostalCode { get; set; }
|
||||
public CipherString Country { get; set; }
|
||||
public CipherString Company { get; set; }
|
||||
public CipherString Email { get; set; }
|
||||
public CipherString Phone { get; set; }
|
||||
public CipherString SSN { get; set; }
|
||||
public CipherString Username { get; set; }
|
||||
public CipherString PassportNumber { get; set; }
|
||||
public CipherString LicenseNumber { get; set; }
|
||||
}
|
||||
}
|
@ -1,58 +1,22 @@
|
||||
using Bit.App.Models.Api;
|
||||
using Bit.App.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public class Login
|
||||
{
|
||||
public Login()
|
||||
{ }
|
||||
public Login() { }
|
||||
|
||||
public Login(LoginData data, IEnumerable<AttachmentData> attachments = null)
|
||||
public Login(CipherData data)
|
||||
{
|
||||
Id = data.Id;
|
||||
UserId = data.UserId;
|
||||
OrganizationId = data.OrganizationId;
|
||||
FolderId = data.FolderId;
|
||||
Name = data.Name != null ? new CipherString(data.Name) : null;
|
||||
Uri = data.Uri != null ? new CipherString(data.Uri) : null;
|
||||
Username = data.Username != null ? new CipherString(data.Username) : null;
|
||||
Password = data.Password != null ? new CipherString(data.Password) : null;
|
||||
Notes = data.Notes != null ? new CipherString(data.Notes) : null;
|
||||
Totp = data.Totp != null ? new CipherString(data.Totp) : null;
|
||||
Favorite = data.Favorite;
|
||||
Edit = data.Edit;
|
||||
OrganizationUseTotp = data.OrganizationUseTotp;
|
||||
Attachments = attachments?.Select(a => new Attachment(a));
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(data.Fields))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fieldModels = JsonConvert.DeserializeObject<IEnumerable<FieldDataModel>>(data.Fields);
|
||||
Fields = fieldModels?.Select(f => new Field(f));
|
||||
}
|
||||
catch(JsonSerializationException) { }
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public CipherString Uri { get; set; }
|
||||
public CipherString Username { get; set; }
|
||||
public CipherString Password { get; set; }
|
||||
public CipherString Notes { get; set; }
|
||||
public CipherString Totp { get; set; }
|
||||
public IEnumerable<Field> Fields { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public bool Edit { get; set; }
|
||||
public bool OrganizationUseTotp { get; set; }
|
||||
public IEnumerable<Attachment> Attachments { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,17 +9,17 @@ namespace Bit.App.Models.Page
|
||||
{
|
||||
public class Login
|
||||
{
|
||||
public Login(Models.Login login)
|
||||
public Login(Models.Cipher cipher)
|
||||
{
|
||||
Id = login.Id;
|
||||
Shared = !string.IsNullOrWhiteSpace(login.OrganizationId);
|
||||
HasAttachments = login.Attachments?.Any() ?? false;
|
||||
FolderId = login.FolderId;
|
||||
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||
Username = login.Username?.Decrypt(login.OrganizationId) ?? " ";
|
||||
Password = new Lazy<string>(() => login.Password?.Decrypt(login.OrganizationId));
|
||||
Uri = new Lazy<string>(() => login.Uri?.Decrypt(login.OrganizationId));
|
||||
Totp = new Lazy<string>(() => login.Totp?.Decrypt(login.OrganizationId));
|
||||
Id = cipher.Id;
|
||||
Shared = !string.IsNullOrWhiteSpace(cipher.OrganizationId);
|
||||
HasAttachments = cipher.Attachments?.Any() ?? false;
|
||||
FolderId = cipher.FolderId;
|
||||
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
|
||||
Username = cipher.Login?.Username?.Decrypt(cipher.OrganizationId) ?? " ";
|
||||
Password = new Lazy<string>(() => cipher.Login?.Password?.Decrypt(cipher.OrganizationId));
|
||||
Uri = new Lazy<string>(() => cipher.Login?.Uri?.Decrypt(cipher.OrganizationId));
|
||||
Totp = new Lazy<string>(() => cipher.Login?.Totp?.Decrypt(cipher.OrganizationId));
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
@ -35,7 +35,7 @@ namespace Bit.App.Models.Page
|
||||
|
||||
public class AutofillLogin : Login
|
||||
{
|
||||
public AutofillLogin(Models.Login login, bool fuzzy = false)
|
||||
public AutofillLogin(Models.Cipher login, bool fuzzy = false)
|
||||
: base(login)
|
||||
{
|
||||
Fuzzy = fuzzy;
|
||||
|
@ -201,23 +201,23 @@ namespace Bit.App.Models.Page
|
||||
}
|
||||
public bool ShowFields => (Fields?.Count ?? 0) > 0;
|
||||
|
||||
public void Update(Login login)
|
||||
public void Update(Cipher cipher)
|
||||
{
|
||||
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||
Username = login.Username?.Decrypt(login.OrganizationId);
|
||||
Password = login.Password?.Decrypt(login.OrganizationId);
|
||||
Uri = login.Uri?.Decrypt(login.OrganizationId);
|
||||
Notes = login.Notes?.Decrypt(login.OrganizationId);
|
||||
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
|
||||
Username = cipher.Login?.Username?.Decrypt(cipher.OrganizationId);
|
||||
Password = cipher.Login?.Password?.Decrypt(cipher.OrganizationId);
|
||||
Uri = cipher.Login?.Uri?.Decrypt(cipher.OrganizationId);
|
||||
Notes = cipher.Notes?.Decrypt(cipher.OrganizationId);
|
||||
|
||||
if(login.Attachments != null)
|
||||
if(cipher.Attachments != null)
|
||||
{
|
||||
var attachments = new List<Attachment>();
|
||||
foreach(var attachment in login.Attachments)
|
||||
foreach(var attachment in cipher.Attachments)
|
||||
{
|
||||
attachments.Add(new Attachment
|
||||
{
|
||||
Id = attachment.Id,
|
||||
Name = attachment.FileName?.Decrypt(login.OrganizationId),
|
||||
Name = attachment.FileName?.Decrypt(cipher.OrganizationId),
|
||||
SizeName = attachment.SizeName,
|
||||
Size = attachment.Size,
|
||||
Url = attachment.Url
|
||||
@ -227,18 +227,18 @@ namespace Bit.App.Models.Page
|
||||
}
|
||||
else
|
||||
{
|
||||
login.Attachments = null;
|
||||
cipher.Attachments = null;
|
||||
}
|
||||
|
||||
if(login.Fields != null)
|
||||
if(cipher.Fields != null)
|
||||
{
|
||||
var fields = new List<Field>();
|
||||
foreach(var field in login.Fields)
|
||||
foreach(var field in cipher.Fields)
|
||||
{
|
||||
fields.Add(new Field
|
||||
{
|
||||
Name = field.Name?.Decrypt(login.OrganizationId),
|
||||
Value = field.Value?.Decrypt(login.OrganizationId),
|
||||
Name = field.Name?.Decrypt(cipher.OrganizationId),
|
||||
Value = field.Value?.Decrypt(cipher.OrganizationId),
|
||||
Type = field.Type
|
||||
});
|
||||
}
|
||||
@ -246,7 +246,7 @@ namespace Bit.App.Models.Page
|
||||
}
|
||||
else
|
||||
{
|
||||
login.Fields = null;
|
||||
cipher.Fields = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
15
src/App/Models/SecureNote.cs
Normal file
15
src/App/Models/SecureNote.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using Bit.App.Enums;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public class SecureNote
|
||||
{
|
||||
public SecureNote(CipherData data)
|
||||
{
|
||||
Type = data.SecureNoteType.Value;
|
||||
}
|
||||
|
||||
public SecureNoteType Type { get; set; }
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
private const string AddedLoginAlertKey = "addedSiteAlert";
|
||||
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
@ -37,7 +37,7 @@ namespace Bit.App.Pages
|
||||
_defaultName = defaultName;
|
||||
_fromAutofill = fromAutofill;
|
||||
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
@ -177,24 +177,31 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
var login = new Login
|
||||
var cipher = new Cipher
|
||||
{
|
||||
Name = NameCell.Entry.Text.Encrypt(),
|
||||
Uri = string.IsNullOrWhiteSpace(UriCell.Entry.Text) ? null : UriCell.Entry.Text.Encrypt(),
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.Entry.Text) ? null : UsernameCell.Entry.Text.Encrypt(),
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.Entry.Text) ? null : PasswordCell.Entry.Text.Encrypt(),
|
||||
Notes = string.IsNullOrWhiteSpace(NotesCell.Editor.Text) ? null : NotesCell.Editor.Text.Encrypt(),
|
||||
Totp = string.IsNullOrWhiteSpace(TotpCell.Entry.Text) ? null : TotpCell.Entry.Text.Encrypt(),
|
||||
Favorite = favoriteCell.On
|
||||
Favorite = favoriteCell.On,
|
||||
Login = new Login
|
||||
{
|
||||
Uri = string.IsNullOrWhiteSpace(UriCell.Entry.Text) ? null :
|
||||
UriCell.Entry.Text.Encrypt(),
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.Entry.Text) ? null :
|
||||
UsernameCell.Entry.Text.Encrypt(),
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.Entry.Text) ? null :
|
||||
PasswordCell.Entry.Text.Encrypt(),
|
||||
Totp = string.IsNullOrWhiteSpace(TotpCell.Entry.Text) ? null :
|
||||
TotpCell.Entry.Text.Encrypt(),
|
||||
}
|
||||
};
|
||||
|
||||
if(FolderCell.Picker.SelectedIndex > 0)
|
||||
{
|
||||
login.FolderId = folders.ElementAt(FolderCell.Picker.SelectedIndex - 1).Id;
|
||||
cipher.FolderId = folders.ElementAt(FolderCell.Picker.SelectedIndex - 1).Id;
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
|
||||
var saveTask = await _loginService.SaveAsync(login);
|
||||
var saveTask = await _cipherService.SaveAsync(cipher);
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
if(saveTask.Succeeded)
|
||||
|
@ -17,7 +17,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class VaultAttachmentsPage : ExtendedContentPage
|
||||
{
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
private readonly IDeviceActionService _deviceActiveService;
|
||||
@ -25,7 +25,7 @@ namespace Bit.App.Pages
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly string _loginId;
|
||||
private Login _login;
|
||||
private Cipher _login;
|
||||
private byte[] _fileBytes;
|
||||
private DateTime? _lastAction;
|
||||
private bool _canUseAttachments = true;
|
||||
@ -34,7 +34,7 @@ namespace Bit.App.Pages
|
||||
: base(true)
|
||||
{
|
||||
_loginId = loginId;
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_deviceActiveService = Resolver.Resolve<IDeviceActionService>();
|
||||
@ -162,7 +162,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
|
||||
var saveTask = await _loginService.EncryptAndSaveAttachmentAsync(_login, _fileBytes, FileLabel.Text);
|
||||
var saveTask = await _cipherService.EncryptAndSaveAttachmentAsync(_login, _fileBytes, FileLabel.Text);
|
||||
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
@ -223,7 +223,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task LoadAttachmentsAsync()
|
||||
{
|
||||
_login = await _loginService.GetByIdAsync(_loginId);
|
||||
_login = await _cipherService.GetByIdAsync(_loginId);
|
||||
if(_login == null)
|
||||
{
|
||||
await Navigation.PopForDeviceAsync();
|
||||
@ -268,7 +268,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Deleting, MaskType.Black);
|
||||
var saveTask = await _loginService.DeleteAttachmentAsync(_login, attachment.Id);
|
||||
var saveTask = await _cipherService.DeleteAttachmentAsync(_login, attachment.Id);
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
if(saveTask.Succeeded)
|
||||
|
@ -17,7 +17,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class VaultAutofillListLoginsPage : ExtendedContentPage
|
||||
{
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IDeviceInfoService _deviceInfoService;
|
||||
private readonly IDeviceActionService _clipboardService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
@ -40,7 +40,7 @@ namespace Bit.App.Pages
|
||||
_name = "--";
|
||||
}
|
||||
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
||||
_clipboardService = Resolver.Resolve<IDeviceActionService>();
|
||||
_settingsService = Resolver.Resolve<ISettingsService>();
|
||||
@ -162,7 +162,7 @@ namespace Bit.App.Pages
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var autofillGroupings = new List<VaultListPageModel.AutofillGrouping>();
|
||||
var logins = await _loginService.GetAllAsync(Uri);
|
||||
var logins = await _cipherService.GetAllAsync(Uri);
|
||||
|
||||
var normalLogins = logins?.Item1.Select(l => new VaultListPageModel.AutofillLogin(l, false))
|
||||
.OrderBy(s => s.Name)
|
||||
|
@ -16,19 +16,19 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class VaultCustomFieldsPage : ExtendedContentPage
|
||||
{
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||
private readonly string _loginId;
|
||||
private Login _login;
|
||||
private Cipher _login;
|
||||
private DateTime? _lastAction;
|
||||
|
||||
public VaultCustomFieldsPage(string loginId)
|
||||
: base(true)
|
||||
{
|
||||
_loginId = loginId;
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||
@ -114,7 +114,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
|
||||
var saveTask = await _loginService.SaveAsync(_login);
|
||||
var saveTask = await _cipherService.SaveAsync(_login);
|
||||
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
@ -148,7 +148,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
_login = await _loginService.GetByIdAsync(_loginId);
|
||||
_login = await _cipherService.GetByIdAsync(_loginId);
|
||||
if(_login == null)
|
||||
{
|
||||
await Navigation.PopForDeviceAsync();
|
||||
|
@ -15,7 +15,7 @@ namespace Bit.App.Pages
|
||||
public class VaultEditLoginPage : ExtendedContentPage
|
||||
{
|
||||
private readonly string _loginId;
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
@ -26,7 +26,7 @@ namespace Bit.App.Pages
|
||||
public VaultEditLoginPage(string loginId)
|
||||
{
|
||||
_loginId = loginId;
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
@ -50,8 +50,8 @@ namespace Bit.App.Pages
|
||||
|
||||
private void Init()
|
||||
{
|
||||
var login = _loginService.GetByIdAsync(_loginId).GetAwaiter().GetResult();
|
||||
if(login == null)
|
||||
var cipher = _cipherService.GetByIdAsync(_loginId).GetAwaiter().GetResult();
|
||||
if(cipher == null)
|
||||
{
|
||||
// TODO: handle error. navigate back? should never happen...
|
||||
return;
|
||||
@ -59,7 +59,7 @@ namespace Bit.App.Pages
|
||||
|
||||
NotesCell = new FormEditorCell(height: 300);
|
||||
NotesCell.Editor.Keyboard = Keyboard.Text;
|
||||
NotesCell.Editor.Text = login.Notes?.Decrypt(login.OrganizationId);
|
||||
NotesCell.Editor.Text = cipher.Notes?.Decrypt(cipher.OrganizationId);
|
||||
|
||||
TotpCell = new FormEntryCell(AppResources.AuthenticatorKey, nextElement: NotesCell.Editor,
|
||||
useButton: _deviceInfo.HasCamera);
|
||||
@ -67,28 +67,28 @@ namespace Bit.App.Pages
|
||||
{
|
||||
TotpCell.Button.Image = "camera";
|
||||
}
|
||||
TotpCell.Entry.Text = login.Totp?.Decrypt(login.OrganizationId);
|
||||
TotpCell.Entry.Text = cipher.Login?.Totp?.Decrypt(cipher.OrganizationId);
|
||||
TotpCell.Entry.DisableAutocapitalize = true;
|
||||
TotpCell.Entry.Autocorrect = false;
|
||||
TotpCell.Entry.FontFamily = Helpers.OnPlatform(iOS: "Menlo-Regular", Android: "monospace", WinPhone: "Courier");
|
||||
|
||||
PasswordCell = new FormEntryCell(AppResources.Password, isPassword: true, nextElement: TotpCell.Entry,
|
||||
useButton: true);
|
||||
PasswordCell.Entry.Text = login.Password?.Decrypt(login.OrganizationId);
|
||||
PasswordCell.Entry.Text = cipher.Login?.Password?.Decrypt(cipher.OrganizationId);
|
||||
PasswordCell.Button.Image = "eye";
|
||||
PasswordCell.Entry.DisableAutocapitalize = true;
|
||||
PasswordCell.Entry.Autocorrect = false;
|
||||
PasswordCell.Entry.FontFamily = Helpers.OnPlatform(iOS: "Menlo-Regular", Android: "monospace", WinPhone: "Courier");
|
||||
|
||||
UsernameCell = new FormEntryCell(AppResources.Username, nextElement: PasswordCell.Entry);
|
||||
UsernameCell.Entry.Text = login.Username?.Decrypt(login.OrganizationId);
|
||||
UsernameCell.Entry.Text = cipher.Login?.Username?.Decrypt(cipher.OrganizationId);
|
||||
UsernameCell.Entry.DisableAutocapitalize = true;
|
||||
UsernameCell.Entry.Autocorrect = false;
|
||||
|
||||
UriCell = new FormEntryCell(AppResources.URI, Keyboard.Url, nextElement: UsernameCell.Entry);
|
||||
UriCell.Entry.Text = login.Uri?.Decrypt(login.OrganizationId);
|
||||
UriCell.Entry.Text = cipher.Login?.Uri?.Decrypt(cipher.OrganizationId);
|
||||
NameCell = new FormEntryCell(AppResources.Name, nextElement: UriCell.Entry);
|
||||
NameCell.Entry.Text = login.Name?.Decrypt(login.OrganizationId);
|
||||
NameCell.Entry.Text = cipher.Name?.Decrypt(cipher.OrganizationId);
|
||||
|
||||
GenerateCell = new ExtendedTextCell
|
||||
{
|
||||
@ -104,7 +104,7 @@ namespace Bit.App.Pages
|
||||
foreach(var folder in folders)
|
||||
{
|
||||
i++;
|
||||
if(folder.Id == login.FolderId)
|
||||
if(folder.Id == cipher.FolderId)
|
||||
{
|
||||
selectedIndex = i;
|
||||
}
|
||||
@ -117,7 +117,7 @@ namespace Bit.App.Pages
|
||||
var favoriteCell = new ExtendedSwitchCell
|
||||
{
|
||||
Text = AppResources.Favorite,
|
||||
On = login.Favorite
|
||||
On = cipher.Favorite
|
||||
};
|
||||
|
||||
AttachmentsCell = new ExtendedTextCell
|
||||
@ -204,30 +204,34 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
login.Name = NameCell.Entry.Text.Encrypt(login.OrganizationId);
|
||||
login.Uri = string.IsNullOrWhiteSpace(UriCell.Entry.Text) ? null :
|
||||
UriCell.Entry.Text.Encrypt(login.OrganizationId);
|
||||
login.Username = string.IsNullOrWhiteSpace(UsernameCell.Entry.Text) ? null :
|
||||
UsernameCell.Entry.Text.Encrypt(login.OrganizationId);
|
||||
login.Password = string.IsNullOrWhiteSpace(PasswordCell.Entry.Text) ? null :
|
||||
PasswordCell.Entry.Text.Encrypt(login.OrganizationId);
|
||||
login.Notes = string.IsNullOrWhiteSpace(NotesCell.Editor.Text) ? null :
|
||||
NotesCell.Editor.Text.Encrypt(login.OrganizationId);
|
||||
login.Totp = string.IsNullOrWhiteSpace(TotpCell.Entry.Text) ? null :
|
||||
TotpCell.Entry.Text.Encrypt(login.OrganizationId);
|
||||
login.Favorite = favoriteCell.On;
|
||||
cipher.Name = NameCell.Entry.Text.Encrypt(cipher.OrganizationId);
|
||||
cipher.Notes = string.IsNullOrWhiteSpace(NotesCell.Editor.Text) ? null :
|
||||
NotesCell.Editor.Text.Encrypt(cipher.OrganizationId);
|
||||
cipher.Favorite = favoriteCell.On;
|
||||
|
||||
cipher.Login = new Models.Login
|
||||
{
|
||||
Uri = string.IsNullOrWhiteSpace(UriCell.Entry.Text) ? null :
|
||||
UriCell.Entry.Text.Encrypt(cipher.OrganizationId),
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.Entry.Text) ? null :
|
||||
UsernameCell.Entry.Text.Encrypt(cipher.OrganizationId),
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.Entry.Text) ? null :
|
||||
PasswordCell.Entry.Text.Encrypt(cipher.OrganizationId),
|
||||
Totp = string.IsNullOrWhiteSpace(TotpCell.Entry.Text) ? null :
|
||||
TotpCell.Entry.Text.Encrypt(cipher.OrganizationId)
|
||||
};
|
||||
|
||||
if(FolderCell.Picker.SelectedIndex > 0)
|
||||
{
|
||||
login.FolderId = folders.ElementAt(FolderCell.Picker.SelectedIndex - 1).Id;
|
||||
cipher.FolderId = folders.ElementAt(FolderCell.Picker.SelectedIndex - 1).Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
login.FolderId = null;
|
||||
cipher.FolderId = null;
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Saving, MaskType.Black);
|
||||
var saveTask = await _loginService.SaveAsync(login);
|
||||
var saveTask = await _cipherService.SaveAsync(cipher);
|
||||
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
@ -405,7 +409,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Deleting, MaskType.Black);
|
||||
var deleteTask = await _loginService.DeleteAsync(_loginId);
|
||||
var deleteTask = await _cipherService.DeleteAsync(_loginId);
|
||||
_userDialogs.HideLoading();
|
||||
|
||||
if(deleteTask.Succeeded)
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.App.Pages
|
||||
public class VaultListLoginsPage : ExtendedContentPage
|
||||
{
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IConnectivity _connectivity;
|
||||
private readonly IDeviceActionService _clipboardService;
|
||||
@ -37,7 +37,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_favorites = favorites;
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_clipboardService = Resolver.Resolve<IDeviceActionService>();
|
||||
@ -310,7 +310,7 @@ namespace Bit.App.Pages
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var foldersTask = _folderService.GetAllAsync();
|
||||
var loginsTask = _favorites ? _loginService.GetAllAsync(true) : _loginService.GetAllAsync();
|
||||
var loginsTask = _favorites ? _cipherService.GetAllAsync(true) : _cipherService.GetAllAsync();
|
||||
await Task.WhenAll(foldersTask, loginsTask);
|
||||
|
||||
var folders = await foldersTask;
|
||||
|
@ -18,7 +18,7 @@ namespace Bit.App.Pages
|
||||
public class VaultViewLoginPage : ExtendedContentPage
|
||||
{
|
||||
private readonly string _loginId;
|
||||
private readonly ILoginService _loginService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IUserDialogs _userDialogs;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly ITokenService _tokenService;
|
||||
@ -27,7 +27,7 @@ namespace Bit.App.Pages
|
||||
public VaultViewLoginPage(string loginId)
|
||||
{
|
||||
_loginId = loginId;
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||
_tokenService = Resolver.Resolve<ITokenService>();
|
||||
@ -161,14 +161,14 @@ namespace Bit.App.Pages
|
||||
NotesCell.Tapped += NotesCell_Tapped;
|
||||
EditItem.InitEvents();
|
||||
|
||||
var login = await _loginService.GetByIdAsync(_loginId);
|
||||
if(login == null)
|
||||
var cipher = await _cipherService.GetByIdAsync(_loginId);
|
||||
if(cipher == null)
|
||||
{
|
||||
await Navigation.PopForDeviceAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
Model.Update(login);
|
||||
Model.Update(cipher);
|
||||
|
||||
if(LoginInformationSection.Contains(UriCell))
|
||||
{
|
||||
@ -211,9 +211,9 @@ namespace Bit.App.Pages
|
||||
{
|
||||
LoginInformationSection.Remove(TotpCodeCell);
|
||||
}
|
||||
if(login.Totp != null && (_tokenService.TokenPremium || login.OrganizationUseTotp))
|
||||
if(cipher.Login?.Totp != null && (_tokenService.TokenPremium || cipher.OrganizationUseTotp))
|
||||
{
|
||||
var totpKey = login.Totp.Decrypt(login.OrganizationId);
|
||||
var totpKey = cipher.Login?.Totp.Decrypt(cipher.OrganizationId);
|
||||
if(!string.IsNullOrWhiteSpace(totpKey))
|
||||
{
|
||||
Model.TotpCode = Crypto.Totp(totpKey);
|
||||
@ -249,7 +249,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
var attachmentCell = new AttachmentViewCell(attachment, async () =>
|
||||
{
|
||||
await OpenAttachmentAsync(login, attachment);
|
||||
await OpenAttachmentAsync(cipher, attachment);
|
||||
});
|
||||
AttachmentCells.Add(attachmentCell);
|
||||
AttachmentsSection.Add(attachmentCell);
|
||||
@ -309,7 +309,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OpenAttachmentAsync(Login login, VaultViewLoginPageModel.Attachment attachment)
|
||||
private async Task OpenAttachmentAsync(Cipher login, VaultViewLoginPageModel.Attachment attachment)
|
||||
{
|
||||
if(!_tokenService.TokenPremium && !login.OrganizationUseTotp)
|
||||
{
|
||||
@ -332,7 +332,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
_userDialogs.ShowLoading(AppResources.Downloading, MaskType.Black);
|
||||
var data = await _loginService.DownloadAndDecryptAttachmentAsync(attachment.Url, login.OrganizationId);
|
||||
var data = await _cipherService.DownloadAndDecryptAttachmentAsync(attachment.Url, login.OrganizationId);
|
||||
_userDialogs.HideLoading();
|
||||
if(data == null)
|
||||
{
|
||||
|
@ -13,9 +13,10 @@ namespace Bit.App.Repositories
|
||||
: base(sqlService)
|
||||
{ }
|
||||
|
||||
public Task<IEnumerable<AttachmentData>> GetAllByLoginIdAsync(string loginId)
|
||||
public Task<IEnumerable<AttachmentData>> GetAllByCipherIdAsync(string cipherId)
|
||||
{
|
||||
var attachments = Connection.Table<AttachmentData>().Where(a => a.LoginId == loginId).Cast<AttachmentData>();
|
||||
var attachments = Connection.Table<AttachmentData>().Where(a => a.LoginId == cipherId)
|
||||
.Cast<AttachmentData>();
|
||||
return Task.FromResult(attachments);
|
||||
}
|
||||
|
||||
|
29
src/App/Repositories/CipherRepository.cs
Normal file
29
src/App/Repositories/CipherRepository.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Repositories
|
||||
{
|
||||
public class CipherRepository : Repository<CipherData, string>, ICipherRepository
|
||||
{
|
||||
public CipherRepository(ISqlService sqlService)
|
||||
: base(sqlService)
|
||||
{ }
|
||||
|
||||
public Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId)
|
||||
{
|
||||
var logins = Connection.Table<CipherData>().Where(l => l.UserId == userId).Cast<CipherData>();
|
||||
return Task.FromResult(logins);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId, bool favorite)
|
||||
{
|
||||
var logins = Connection.Table<CipherData>().Where(l => l.UserId == userId && l.Favorite == favorite)
|
||||
.Cast<CipherData>();
|
||||
return Task.FromResult(logins);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,11 +22,11 @@ namespace Bit.App.Repositories
|
||||
public override Task DeleteAsync(string id)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
DeleteWithLoginUpdateAsync(id, now);
|
||||
DeleteWithCipherUpdateAsync(id, now);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task DeleteWithLoginUpdateAsync(string id, DateTime revisionDate)
|
||||
public Task DeleteWithCipherUpdateAsync(string id, DateTime revisionDate)
|
||||
{
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
|
@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.Data;
|
||||
|
||||
namespace Bit.App.Repositories
|
||||
{
|
||||
public class LoginRepository : Repository<LoginData, string>, ILoginRepository
|
||||
{
|
||||
public LoginRepository(ISqlService sqlService)
|
||||
: base(sqlService)
|
||||
{ }
|
||||
|
||||
public Task<IEnumerable<LoginData>> GetAllByUserIdAsync(string userId)
|
||||
{
|
||||
var logins = Connection.Table<LoginData>().Where(l => l.UserId == userId).Cast<LoginData>();
|
||||
return Task.FromResult(logins);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<LoginData>> GetAllByUserIdAsync(string userId, bool favorite)
|
||||
{
|
||||
var logins = Connection.Table<LoginData>().Where(l => l.UserId == userId && l.Favorite == favorite)
|
||||
.Cast<LoginData>();
|
||||
return Task.FromResult(logins);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,26 +11,26 @@ using System.Net.Http;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
public class LoginService : ILoginService
|
||||
public class CipherService : ICipherService
|
||||
{
|
||||
private readonly string[] _ignoredSearchTerms = new string[] { "com", "net", "org", "android",
|
||||
"io", "co", "uk", "au", "nz", "fr", "de", "tv", "info", "app", "apps", "eu", "me", "dev", "jp", "mobile" };
|
||||
private readonly ILoginRepository _loginRepository;
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly IAttachmentRepository _attachmentRepository;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly ICipherApiRepository _cipherApiRepository;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
|
||||
public LoginService(
|
||||
ILoginRepository loginRepository,
|
||||
public CipherService(
|
||||
ICipherRepository cipherRepository,
|
||||
IAttachmentRepository attachmentRepository,
|
||||
IAuthService authService,
|
||||
ICipherApiRepository cipherApiRepository,
|
||||
ISettingsService settingsService,
|
||||
ICryptoService cryptoService)
|
||||
{
|
||||
_loginRepository = loginRepository;
|
||||
_cipherRepository = cipherRepository;
|
||||
_attachmentRepository = attachmentRepository;
|
||||
_authService = authService;
|
||||
_cipherApiRepository = cipherApiRepository;
|
||||
@ -38,38 +38,38 @@ namespace Bit.App.Services
|
||||
_cryptoService = cryptoService;
|
||||
}
|
||||
|
||||
public async Task<Login> GetByIdAsync(string id)
|
||||
public async Task<Cipher> GetByIdAsync(string id)
|
||||
{
|
||||
var data = await _loginRepository.GetByIdAsync(id);
|
||||
var data = await _cipherRepository.GetByIdAsync(id);
|
||||
if(data == null || data.UserId != _authService.UserId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var attachments = await _attachmentRepository.GetAllByLoginIdAsync(id);
|
||||
var login = new Login(data, attachments);
|
||||
return login;
|
||||
var attachments = await _attachmentRepository.GetAllByCipherIdAsync(id);
|
||||
var cipher = new Cipher(data, attachments);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Login>> GetAllAsync()
|
||||
public async Task<IEnumerable<Cipher>> GetAllAsync()
|
||||
{
|
||||
var attachmentData = await _attachmentRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
var attachmentDict = attachmentData.GroupBy(a => a.LoginId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
var data = await _loginRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
var logins = data.Select(f => new Login(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null));
|
||||
var data = await _cipherRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
var logins = data.Select(f => new Cipher(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null));
|
||||
return logins;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Login>> GetAllAsync(bool favorites)
|
||||
public async Task<IEnumerable<Cipher>> GetAllAsync(bool favorites)
|
||||
{
|
||||
var attachmentData = await _attachmentRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
var attachmentDict = attachmentData.GroupBy(a => a.LoginId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
var data = await _loginRepository.GetAllByUserIdAsync(_authService.UserId, favorites);
|
||||
var logins = data.Select(f => new Login(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null));
|
||||
var data = await _cipherRepository.GetAllByUserIdAsync(_authService.UserId, favorites);
|
||||
var logins = data.Select(f => new Cipher(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null));
|
||||
return logins;
|
||||
}
|
||||
|
||||
public async Task<Tuple<IEnumerable<Login>, IEnumerable<Login>>> GetAllAsync(string uriString)
|
||||
public async Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(uriString))
|
||||
{
|
||||
@ -125,9 +125,9 @@ namespace Bit.App.Services
|
||||
|
||||
var matchingDomainsArray = matchingDomains.ToArray();
|
||||
var matchingFuzzyDomainsArray = matchingFuzzyDomains.ToArray();
|
||||
var matchingLogins = new List<Login>();
|
||||
var matchingFuzzyLogins = new List<Login>();
|
||||
var logins = await _loginRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
var matchingLogins = new List<Cipher>();
|
||||
var matchingFuzzyLogins = new List<Cipher>();
|
||||
var logins = await _cipherRepository.GetAllByUserIdAsync(_authService.UserId);
|
||||
foreach(var login in logins)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(login.Uri))
|
||||
@ -143,12 +143,12 @@ namespace Bit.App.Services
|
||||
|
||||
if(Array.IndexOf(matchingDomainsArray, loginUriString) >= 0)
|
||||
{
|
||||
matchingLogins.Add(new Login(login));
|
||||
matchingLogins.Add(new Cipher(login));
|
||||
continue;
|
||||
}
|
||||
else if(mobileApp && Array.IndexOf(matchingFuzzyDomainsArray, loginUriString) >= 0)
|
||||
{
|
||||
matchingFuzzyLogins.Add(new Login(login));
|
||||
matchingFuzzyLogins.Add(new Cipher(login));
|
||||
continue;
|
||||
}
|
||||
else if(!mobileApp)
|
||||
@ -156,7 +156,7 @@ namespace Bit.App.Services
|
||||
var info = InfoFromMobileAppUri(loginUriString);
|
||||
if(info?.Item1 != null && Array.IndexOf(matchingDomainsArray, info.Item1) >= 0)
|
||||
{
|
||||
matchingFuzzyLogins.Add(new Login(login));
|
||||
matchingFuzzyLogins.Add(new Cipher(login));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -170,12 +170,12 @@ namespace Bit.App.Services
|
||||
|
||||
if(Array.IndexOf(matchingDomainsArray, loginDomainName) >= 0)
|
||||
{
|
||||
matchingLogins.Add(new Login(login));
|
||||
matchingLogins.Add(new Cipher(login));
|
||||
continue;
|
||||
}
|
||||
else if(mobileApp && Array.IndexOf(matchingFuzzyDomainsArray, loginDomainName) >= 0)
|
||||
{
|
||||
matchingFuzzyLogins.Add(new Login(login));
|
||||
matchingFuzzyLogins.Add(new Cipher(login));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -197,7 +197,7 @@ namespace Bit.App.Services
|
||||
|
||||
if(addedFromSearchTerm)
|
||||
{
|
||||
matchingFuzzyLogins.Add(new Login(login));
|
||||
matchingFuzzyLogins.Add(new Cipher(login));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -209,10 +209,10 @@ namespace Bit.App.Services
|
||||
}
|
||||
}
|
||||
|
||||
return new Tuple<IEnumerable<Login>, IEnumerable<Login>>(matchingLogins, matchingFuzzyLogins);
|
||||
return new Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>>(matchingLogins, matchingFuzzyLogins);
|
||||
}
|
||||
|
||||
public async Task<ApiResult<CipherResponse>> SaveAsync(Login login)
|
||||
public async Task<ApiResult<CipherResponse>> SaveAsync(Cipher login)
|
||||
{
|
||||
ApiResult<CipherResponse> response = null;
|
||||
var request = new CipherRequest(login);
|
||||
@ -228,15 +228,15 @@ namespace Bit.App.Services
|
||||
|
||||
if(response.Succeeded)
|
||||
{
|
||||
var data = new LoginData(response.Result, _authService.UserId);
|
||||
var data = new CipherData(response.Result, _authService.UserId);
|
||||
if(login.Id == null)
|
||||
{
|
||||
await _loginRepository.InsertAsync(data);
|
||||
await _cipherRepository.InsertAsync(data);
|
||||
login.Id = data.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
await _loginRepository.UpdateAsync(data);
|
||||
await _cipherRepository.UpdateAsync(data);
|
||||
}
|
||||
}
|
||||
else if(response.StatusCode == System.Net.HttpStatusCode.Forbidden
|
||||
@ -253,7 +253,7 @@ namespace Bit.App.Services
|
||||
var response = await _cipherApiRepository.DeleteAsync(id);
|
||||
if(response.Succeeded)
|
||||
{
|
||||
await _loginRepository.DeleteAsync(id);
|
||||
await _cipherRepository.DeleteAsync(id);
|
||||
}
|
||||
else if(response.StatusCode == System.Net.HttpStatusCode.Forbidden
|
||||
|| response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
@ -298,7 +298,7 @@ namespace Bit.App.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Login login, byte[] data, string fileName)
|
||||
public async Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Cipher login, byte[] data, string fileName)
|
||||
{
|
||||
var encFileName = fileName.Encrypt(login.OrganizationId);
|
||||
var encBytes = _cryptoService.EncryptToBytes(data,
|
||||
@ -323,7 +323,7 @@ namespace Bit.App.Services
|
||||
return response;
|
||||
}
|
||||
|
||||
public async Task<ApiResult> DeleteAttachmentAsync(Login login, string attachmentId)
|
||||
public async Task<ApiResult> DeleteAttachmentAsync(Cipher login, string attachmentId)
|
||||
{
|
||||
var response = await _cipherApiRepository.DeleteAttachmentAsync(login.Id, attachmentId);
|
||||
if(response.Succeeded)
|
@ -17,7 +17,7 @@ namespace Bit.App.Services
|
||||
public void CreateTables()
|
||||
{
|
||||
_connection.CreateTable<FolderData>();
|
||||
_connection.CreateTable<LoginData>();
|
||||
_connection.CreateTable<CipherData>();
|
||||
_connection.CreateTable<AttachmentData>();
|
||||
_connection.CreateTable<SettingsData>();
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ namespace Bit.App.Services
|
||||
{
|
||||
break;
|
||||
}
|
||||
_syncService.SyncDeleteLoginAsync(loginDeleteMessage.Id);
|
||||
_syncService.SyncDeleteCipherAsync(loginDeleteMessage.Id);
|
||||
break;
|
||||
case Enums.PushType.SyncCiphers:
|
||||
case Enums.PushType.SyncVault:
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.App.Services
|
||||
private readonly ISettingsApiRepository _settingsApiRepository;
|
||||
private readonly ISyncApiRepository _syncApiRepository;
|
||||
private readonly IFolderRepository _folderRepository;
|
||||
private readonly ILoginRepository _loginRepository;
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly IAttachmentRepository _attachmentRepository;
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly IAuthService _authService;
|
||||
@ -35,7 +35,7 @@ namespace Bit.App.Services
|
||||
ISettingsApiRepository settingsApiRepository,
|
||||
ISyncApiRepository syncApiRepository,
|
||||
IFolderRepository folderRepository,
|
||||
ILoginRepository loginRepository,
|
||||
ICipherRepository cipherRepository,
|
||||
IAttachmentRepository attachmentRepository,
|
||||
ISettingsRepository settingsRepository,
|
||||
IAuthService authService,
|
||||
@ -49,7 +49,7 @@ namespace Bit.App.Services
|
||||
_settingsApiRepository = settingsApiRepository;
|
||||
_syncApiRepository = syncApiRepository;
|
||||
_folderRepository = folderRepository;
|
||||
_loginRepository = loginRepository;
|
||||
_cipherRepository = cipherRepository;
|
||||
_attachmentRepository = attachmentRepository;
|
||||
_settingsRepository = settingsRepository;
|
||||
_authService = authService;
|
||||
@ -77,40 +77,32 @@ namespace Bit.App.Services
|
||||
|
||||
try
|
||||
{
|
||||
switch(cipher.Result.Type)
|
||||
var cipherData = new CipherData(cipher.Result, _authService.UserId);
|
||||
await _cipherRepository.UpsertAsync(cipherData).ConfigureAwait(false);
|
||||
|
||||
var localAttachments = (await _attachmentRepository.GetAllByCipherIdAsync(cipherData.Id)
|
||||
.ConfigureAwait(false));
|
||||
|
||||
if(cipher.Result.Attachments != null)
|
||||
{
|
||||
case Enums.CipherType.Login:
|
||||
var loginData = new LoginData(cipher.Result, _authService.UserId);
|
||||
await _loginRepository.UpsertAsync(loginData).ConfigureAwait(false);
|
||||
foreach(var attachment in cipher.Result.Attachments)
|
||||
{
|
||||
var attachmentData = new AttachmentData(attachment, cipherData.Id);
|
||||
await _attachmentRepository.UpsertAsync(attachmentData).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
var localAttachments = (await _attachmentRepository.GetAllByLoginIdAsync(loginData.Id)
|
||||
.ConfigureAwait(false));
|
||||
|
||||
if(cipher.Result.Attachments != null)
|
||||
if(localAttachments != null)
|
||||
{
|
||||
foreach(var attachment in localAttachments
|
||||
.Where(a => !cipher.Result.Attachments.Any(sa => sa.Id == a.Id)))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach(var attachment in cipher.Result.Attachments)
|
||||
{
|
||||
var attachmentData = new AttachmentData(attachment, loginData.Id);
|
||||
await _attachmentRepository.UpsertAsync(attachmentData).ConfigureAwait(false);
|
||||
}
|
||||
await _attachmentRepository.DeleteAsync(attachment.Id).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if(localAttachments != null)
|
||||
{
|
||||
foreach(var attachment in localAttachments
|
||||
.Where(a => !cipher.Result.Attachments.Any(sa => sa.Id == a.Id)))
|
||||
{
|
||||
try
|
||||
{
|
||||
await _attachmentRepository.DeleteAsync(attachment.Id).ConfigureAwait(false);
|
||||
}
|
||||
catch(SQLite.SQLiteException) { }
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SyncCompleted(false);
|
||||
return false;
|
||||
catch(SQLite.SQLiteException) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(SQLite.SQLiteException)
|
||||
@ -164,7 +156,7 @@ namespace Bit.App.Services
|
||||
|
||||
try
|
||||
{
|
||||
await _folderRepository.DeleteWithLoginUpdateAsync(id, revisionDate).ConfigureAwait(false);
|
||||
await _folderRepository.DeleteWithCipherUpdateAsync(id, revisionDate).ConfigureAwait(false);
|
||||
SyncCompleted(true);
|
||||
return true;
|
||||
}
|
||||
@ -175,7 +167,7 @@ namespace Bit.App.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> SyncDeleteLoginAsync(string id)
|
||||
public async Task<bool> SyncDeleteCipherAsync(string id)
|
||||
{
|
||||
if(!_authService.IsAuthenticated)
|
||||
{
|
||||
@ -186,7 +178,7 @@ namespace Bit.App.Services
|
||||
|
||||
try
|
||||
{
|
||||
await _loginRepository.DeleteAsync(id).ConfigureAwait(false);
|
||||
await _cipherRepository.DeleteAsync(id).ConfigureAwait(false);
|
||||
SyncCompleted(true);
|
||||
return true;
|
||||
}
|
||||
@ -277,17 +269,16 @@ namespace Bit.App.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
var loginsDict = syncResponse.Result.Ciphers.Where(c => c.Type == Enums.CipherType.Login)
|
||||
.ToDictionary(s => s.Id);
|
||||
var ciphersDict = syncResponse.Result.Ciphers.ToDictionary(s => s.Id);
|
||||
var foldersDict = syncResponse.Result.Folders.ToDictionary(f => f.Id);
|
||||
|
||||
var loginTask = SyncLoginsAsync(loginsDict);
|
||||
var cipherTask = SyncCiphersAsync(ciphersDict);
|
||||
var folderTask = SyncFoldersAsync(foldersDict);
|
||||
var domainsTask = SyncDomainsAsync(syncResponse.Result.Domains);
|
||||
var profileTask = SyncProfileKeysAsync(syncResponse.Result.Profile);
|
||||
await Task.WhenAll(loginTask, folderTask, domainsTask, profileTask).ConfigureAwait(false);
|
||||
await Task.WhenAll(cipherTask, folderTask, domainsTask, profileTask).ConfigureAwait(false);
|
||||
|
||||
if(folderTask.Exception != null || loginTask.Exception != null || domainsTask.Exception != null ||
|
||||
if(folderTask.Exception != null || cipherTask.Exception != null || domainsTask.Exception != null ||
|
||||
profileTask.Exception != null)
|
||||
{
|
||||
SyncCompleted(false);
|
||||
@ -361,14 +352,14 @@ namespace Bit.App.Services
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SyncLoginsAsync(IDictionary<string, CipherResponse> serverLogins)
|
||||
private async Task SyncCiphersAsync(IDictionary<string, CipherResponse> serviceCiphers)
|
||||
{
|
||||
if(!_authService.IsAuthenticated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var localLogins = (await _loginRepository.GetAllByUserIdAsync(_authService.UserId)
|
||||
var localCiphers = (await _cipherRepository.GetAllByUserIdAsync(_authService.UserId)
|
||||
.ConfigureAwait(false))
|
||||
.GroupBy(s => s.Id)
|
||||
.Select(s => s.First())
|
||||
@ -379,7 +370,7 @@ namespace Bit.App.Services
|
||||
.GroupBy(a => a.LoginId)
|
||||
.ToDictionary(g => g.Key);
|
||||
|
||||
foreach(var serverLogin in serverLogins)
|
||||
foreach(var serverCipher in serviceCiphers)
|
||||
{
|
||||
if(!_authService.IsAuthenticated)
|
||||
{
|
||||
@ -388,24 +379,25 @@ namespace Bit.App.Services
|
||||
|
||||
try
|
||||
{
|
||||
var localLogin = localLogins.ContainsKey(serverLogin.Value.Id) ? localLogins[serverLogin.Value.Id] : null;
|
||||
var localCipher = localCiphers.ContainsKey(serverCipher.Value.Id) ?
|
||||
localCiphers[serverCipher.Value.Id] : null;
|
||||
|
||||
var data = new LoginData(serverLogin.Value, _authService.UserId);
|
||||
await _loginRepository.UpsertAsync(data).ConfigureAwait(false);
|
||||
var data = new CipherData(serverCipher.Value, _authService.UserId);
|
||||
await _cipherRepository.UpsertAsync(data).ConfigureAwait(false);
|
||||
|
||||
if(serverLogin.Value.Attachments != null)
|
||||
if(serverCipher.Value.Attachments != null)
|
||||
{
|
||||
foreach(var attachment in serverLogin.Value.Attachments)
|
||||
foreach(var attachment in serverCipher.Value.Attachments)
|
||||
{
|
||||
var attachmentData = new AttachmentData(attachment, data.Id);
|
||||
await _attachmentRepository.UpsertAsync(attachmentData).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if(localLogin != null && localAttachments != null && localAttachments.ContainsKey(localLogin.Id))
|
||||
if(localCipher != null && localAttachments != null && localAttachments.ContainsKey(localCipher.Id))
|
||||
{
|
||||
foreach(var attachment in localAttachments[localLogin.Id]
|
||||
.Where(a => !serverLogin.Value.Attachments.Any(sa => sa.Id == a.Id)))
|
||||
foreach(var attachment in localAttachments[localCipher.Id]
|
||||
.Where(a => !serverCipher.Value.Attachments.Any(sa => sa.Id == a.Id)))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -418,11 +410,11 @@ namespace Bit.App.Services
|
||||
catch(SQLite.SQLiteException) { }
|
||||
}
|
||||
|
||||
foreach(var login in localLogins.Where(localLogin => !serverLogins.ContainsKey(localLogin.Key)))
|
||||
foreach(var cipher in localCiphers.Where(local => !serviceCiphers.ContainsKey(local.Key)))
|
||||
{
|
||||
try
|
||||
{
|
||||
await _loginRepository.DeleteAsync(login.Value.Id).ConfigureAwait(false);
|
||||
await _cipherRepository.DeleteAsync(cipher.Value.Id).ConfigureAwait(false);
|
||||
}
|
||||
catch(SQLite.SQLiteException) { }
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ namespace Bit.UWP
|
||||
container.RegisterSingleton<IKeyDerivationService, KeyDerivationService>();
|
||||
container.RegisterSingleton<IAuthService, AuthService>();
|
||||
container.RegisterSingleton<IFolderService, FolderService>();
|
||||
container.RegisterSingleton<ILoginService, LoginService>();
|
||||
container.RegisterSingleton<ICipherService, CipherService>();
|
||||
container.RegisterSingleton<ISyncService, SyncService>();
|
||||
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
|
||||
container.RegisterSingleton<IAppIdService, AppIdService>();
|
||||
@ -108,7 +108,7 @@ namespace Bit.UWP
|
||||
// Repositories
|
||||
container.RegisterSingleton<IFolderRepository, FolderRepository>();
|
||||
container.RegisterSingleton<IFolderApiRepository, FolderApiRepository>();
|
||||
container.RegisterSingleton<ILoginRepository, LoginRepository>();
|
||||
container.RegisterSingleton<ICipherRepository, CipherRepository>();
|
||||
container.RegisterSingleton<IAttachmentRepository, AttachmentRepository>();
|
||||
container.RegisterSingleton<IConnectApiRepository, ConnectApiRepository>();
|
||||
container.RegisterSingleton<IDeviceApiRepository, DeviceApiRepository>();
|
||||
|
@ -277,7 +277,7 @@ namespace Bit.iOS.Extension
|
||||
container.RegisterSingleton<IKeyDerivationService, CommonCryptoKeyDerivationService>();
|
||||
container.RegisterSingleton<IAuthService, AuthService>();
|
||||
container.RegisterSingleton<IFolderService, FolderService>();
|
||||
container.RegisterSingleton<ILoginService, LoginService>();
|
||||
container.RegisterSingleton<ICipherService, CipherService>();
|
||||
container.RegisterSingleton<ISyncService, SyncService>();
|
||||
container.RegisterSingleton<IPasswordGenerationService, PasswordGenerationService>();
|
||||
container.RegisterSingleton<IAppIdService, AppIdService>();
|
||||
@ -294,7 +294,7 @@ namespace Bit.iOS.Extension
|
||||
// Repositories
|
||||
container.RegisterSingleton<IFolderRepository, FolderRepository>();
|
||||
container.RegisterSingleton<IFolderApiRepository, FolderApiRepository>();
|
||||
container.RegisterSingleton<ILoginRepository, LoginRepository>();
|
||||
container.RegisterSingleton<ICipherRepository, CipherRepository>();
|
||||
container.RegisterSingleton<IAttachmentRepository, AttachmentRepository>();
|
||||
container.RegisterSingleton<IConnectApiRepository, ConnectApiRepository>();
|
||||
container.RegisterSingleton<ISettingsRepository, SettingsRepository>();
|
||||
|
@ -19,7 +19,7 @@ namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LoginAddViewController : ExtendedUITableViewController
|
||||
{
|
||||
private ILoginService _loginService;
|
||||
private ICipherService _cipherService;
|
||||
private IFolderService _folderService;
|
||||
private IConnectivity _connectivity;
|
||||
private IEnumerable<Folder> _folders;
|
||||
@ -49,7 +49,7 @@ namespace Bit.iOS.Extension
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_connectivity = Resolver.Resolve<IConnectivity>();
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||
@ -151,18 +151,21 @@ namespace Bit.iOS.Extension
|
||||
return;
|
||||
}
|
||||
|
||||
var login = new Login
|
||||
var cipher = new Cipher
|
||||
{
|
||||
Uri = string.IsNullOrWhiteSpace(UriCell.TextField.Text) ? null : UriCell.TextField.Text.Encrypt(),
|
||||
Name = string.IsNullOrWhiteSpace(NameCell.TextField.Text) ? null : NameCell.TextField.Text.Encrypt(),
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.TextField.Text) ? null : UsernameCell.TextField.Text.Encrypt(),
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.TextField.Text) ? null : PasswordCell.TextField.Text.Encrypt(),
|
||||
Notes = string.IsNullOrWhiteSpace(NotesCell.TextView.Text) ? null : NotesCell.TextView.Text.Encrypt(),
|
||||
Favorite = FavoriteCell.Switch.On,
|
||||
FolderId = FolderCell.SelectedIndex == 0 ? null : _folders.ElementAtOrDefault(FolderCell.SelectedIndex - 1)?.Id
|
||||
FolderId = FolderCell.SelectedIndex == 0 ? null : _folders.ElementAtOrDefault(FolderCell.SelectedIndex - 1)?.Id,
|
||||
Login = new Login
|
||||
{
|
||||
Uri = string.IsNullOrWhiteSpace(UriCell.TextField.Text) ? null : UriCell.TextField.Text.Encrypt(),
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.TextField.Text) ? null : UsernameCell.TextField.Text.Encrypt(),
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.TextField.Text) ? null : PasswordCell.TextField.Text.Encrypt()
|
||||
}
|
||||
};
|
||||
|
||||
var saveTask = _loginService.SaveAsync(login);
|
||||
var saveTask = _cipherService.SaveAsync(cipher);
|
||||
var loadingAlert = Dialogs.CreateLoadingAlert(AppResources.Saving);
|
||||
PresentViewController(loadingAlert, true, null);
|
||||
await saveTask;
|
||||
|
@ -105,7 +105,7 @@ namespace Bit.iOS.Extension
|
||||
private IEnumerable<LoginViewModel> _tableItems = new List<LoginViewModel>();
|
||||
private Context _context;
|
||||
private LoginListViewController _controller;
|
||||
private ILoginService _loginService;
|
||||
private ICipherService _cipherService;
|
||||
private ISettings _settings;
|
||||
private bool _isPremium;
|
||||
|
||||
@ -114,15 +114,15 @@ namespace Bit.iOS.Extension
|
||||
_context = controller.Context;
|
||||
_controller = controller;
|
||||
_isPremium = Resolver.Resolve<ITokenService>()?.TokenPremium ?? false;
|
||||
_loginService = Resolver.Resolve<ILoginService>();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
}
|
||||
|
||||
public async Task LoadItemsAsync()
|
||||
{
|
||||
var combinedLogins = new List<Login>();
|
||||
var combinedLogins = new List<Cipher>();
|
||||
|
||||
var logins = await _loginService.GetAllAsync(_context.UrlString);
|
||||
var logins = await _cipherService.GetAllAsync(_context.UrlString);
|
||||
if(logins?.Item1 != null)
|
||||
{
|
||||
combinedLogins.AddRange(logins.Item1);
|
||||
|
@ -7,7 +7,7 @@ namespace Bit.iOS.Extension.Models
|
||||
{
|
||||
public class LoginViewModel
|
||||
{
|
||||
public LoginViewModel(Login login)
|
||||
public LoginViewModel(Cipher login)
|
||||
{
|
||||
Id = login.Id;
|
||||
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||
|
@ -256,7 +256,7 @@ namespace Bit.iOS
|
||||
container.RegisterSingleton<IKeyDerivationService, CommonCryptoKeyDerivationService>();
|
||||
container.RegisterSingleton<IAuthService, AuthService>();
|
||||
container.RegisterSingleton<IFolderService, FolderService>();
|
||||
container.RegisterSingleton<ILoginService, LoginService>();
|
||||
container.RegisterSingleton<ICipherService, CipherService>();
|
||||
container.RegisterSingleton<ISyncService, SyncService>();
|
||||
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
|
||||
container.RegisterSingleton<IAppIdService, AppIdService>();
|
||||
@ -276,7 +276,7 @@ namespace Bit.iOS
|
||||
// Repositories
|
||||
container.RegisterSingleton<IFolderRepository, FolderRepository>();
|
||||
container.RegisterSingleton<IFolderApiRepository, FolderApiRepository>();
|
||||
container.RegisterSingleton<ILoginRepository, LoginRepository>();
|
||||
container.RegisterSingleton<ICipherRepository, CipherRepository>();
|
||||
container.RegisterSingleton<IAttachmentRepository, AttachmentRepository>();
|
||||
container.RegisterSingleton<IConnectApiRepository, ConnectApiRepository>();
|
||||
container.RegisterSingleton<IDeviceApiRepository, DeviceApiRepository>();
|
||||
|
Loading…
Reference in New Issue
Block a user