1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-26 05:03:39 +00:00

reset for v2

This commit is contained in:
Kyle Spearrin
2019-03-27 16:23:00 -04:00
parent 5a7f106e3e
commit 297beac169
1180 changed files with 0 additions and 126197 deletions

View File

@@ -1,9 +0,0 @@
using System.Net;
namespace Bit.App.Models.Api
{
public class ApiError
{
public string Message { get; set; }
}
}

View File

@@ -1,75 +0,0 @@
using System.Collections.Generic;
using System.Net;
namespace Bit.App.Models.Api
{
public class ApiResult<T>
{
private List<ApiError> m_errors = new List<ApiError>();
public bool Succeeded { get; private set; }
public T Result { get; set; }
public IEnumerable<ApiError> Errors => m_errors;
public HttpStatusCode StatusCode { get; private set; }
public static ApiResult<T> Success(T result, HttpStatusCode statusCode)
{
return new ApiResult<T>
{
Succeeded = true,
Result = result,
StatusCode = statusCode
};
}
public static ApiResult<T> Failed(HttpStatusCode statusCode, params ApiError[] errors)
{
var result = new ApiResult<T>
{
Succeeded = false,
StatusCode = statusCode
};
if(errors != null)
{
result.m_errors.AddRange(errors);
}
return result;
}
}
public class ApiResult
{
private List<ApiError> m_errors = new List<ApiError>();
public bool Succeeded { get; private set; }
public IEnumerable<ApiError> Errors => m_errors;
public HttpStatusCode StatusCode { get; private set; }
public static ApiResult Success(HttpStatusCode statusCode)
{
return new ApiResult
{
Succeeded = true,
StatusCode = statusCode
};
}
public static ApiResult Failed(HttpStatusCode statusCode, params ApiError[] errors)
{
var result = new ApiResult
{
Succeeded = false,
StatusCode = statusCode
};
if(errors != null)
{
result.m_errors.AddRange(errors);
}
return result;
}
}
}

View File

@@ -1,24 +0,0 @@
namespace Bit.App.Models.Api
{
public class CardType
{
public 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; }
}
}

View File

@@ -1,18 +0,0 @@
namespace Bit.App.Models.Api
{
public class FieldType
{
public FieldType() { }
public FieldType(Field field)
{
Type = field.Type;
Name = field.Name?.EncryptedString;
Value = field.Value?.EncryptedString;
}
public Enums.FieldType Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@@ -1,48 +0,0 @@
namespace Bit.App.Models.Api
{
public class IdentityType
{
public 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; }
}
}

View File

@@ -1,26 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models.Api
{
public class LoginType
{
public LoginType() { }
public LoginType(Cipher cipher)
{
Uris = cipher.Login.Uris?.Select(u => new LoginUriType(u));
Username = cipher.Login.Username?.EncryptedString;
Password = cipher.Login.Password?.EncryptedString;
PasswordRevisionDate = cipher.Login.PasswordRevisionDate;
Totp = cipher.Login.Totp?.EncryptedString;
}
public IEnumerable<LoginUriType> Uris { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public System.DateTime? PasswordRevisionDate { get; set; }
public string Totp { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class LoginUriType
{
public LoginUriType() { }
public LoginUriType(LoginUri u)
{
Uri = u.Uri?.EncryptedString;
Match = u.Match;
}
public string Uri { get; set; }
public UriMatchType? Match { get; set; }
}
}

View File

@@ -1,61 +0,0 @@
using Bit.App.Enums;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models.Api
{
public class CipherRequest
{
public CipherRequest(Cipher cipher)
{
Type = cipher.Type;
OrganizationId = cipher.OrganizationId;
FolderId = cipher.FolderId;
Name = cipher.Name?.EncryptedString;
Notes = cipher.Notes?.EncryptedString;
Favorite = cipher.Favorite;
if(cipher.Fields != null)
{
Fields = cipher.Fields.Select(f => new FieldType(f));
}
if(cipher.PasswordHistory != null)
{
PasswordHistory = cipher.PasswordHistory.Select(h => new PasswordHistoryRequest(h));
}
switch(Type)
{
case CipherType.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;
}
}
public CipherType Type { get; set; }
public string OrganizationId { get; set; }
public string FolderId { get; set; }
public bool Favorite { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldType> Fields { get; set; }
public IEnumerable<PasswordHistoryRequest> PasswordHistory { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }
public IdentityType Identity { get; set; }
public SecureNoteType SecureNote { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Bit.App.Abstractions;
using Bit.App.Enums;
using Xamarin.Forms;
namespace Bit.App.Models.Api
{
public class DeviceRequest
{
public DeviceRequest() { }
public DeviceRequest(IAppIdService appIdService, IDeviceInfoService deviceInfoService)
{
Identifier = appIdService.AppId;
Name = deviceInfoService.Model;
Type = Device.RuntimePlatform == Device.Android ? DeviceType.Android : DeviceType.iOS;
}
public DeviceType Type { get; set; }
public string Name { get; set; }
public string Identifier { get; set; }
public string PushToken { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Models.Api
{
public class DeviceTokenRequest
{
public DeviceTokenRequest(string token)
{
PushToken = token;
}
public string PushToken { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Models.Api
{
public class FolderRequest
{
public FolderRequest(Folder folder)
{
Name = folder.Name?.EncryptedString;
}
public string Name { get; set; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Models.Api
{
public class PasswordHintRequest
{
public string Email { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
namespace Bit.App.Models.Api
{
public class PasswordHistoryRequest
{
public PasswordHistoryRequest(PasswordHistory ph)
{
Password = ph.Password?.EncryptedString;
LastUsedDate = ph.LastUsedDate;
}
public string Password { get; set; }
public System.DateTime LastUsedDate { get; set; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Models.Api
{
public class PreloginRequest
{
public string Email { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class RegisterRequest
{
public string Name { get; set; }
public string Email { get; set; }
public string MasterPasswordHash { get; set; }
public string MasterPasswordHint { get; set; }
public string Key { get; set; }
public KdfType Kdf { get; set; }
public int KdfIterations { get; set; }
}
}

View File

@@ -1,45 +0,0 @@
using Bit.App.Enums;
using System;
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class TokenRequest
{
public string Email { get; set; }
public string MasterPasswordHash { get; set; }
public string Token { get; set; }
public TwoFactorProviderType? Provider { get; set; }
public DeviceRequest Device { get; set; }
public bool Remember { get; set; }
public IDictionary<string, string> ToIdentityTokenRequest()
{
var dict = new Dictionary<string, string>
{
{ "grant_type", "password" },
{ "username", Email },
{ "password", MasterPasswordHash },
{ "scope", "api offline_access" },
{ "client_id", "mobile" }
};
if(Device != null)
{
dict.Add("DeviceType", Device.Type.ToString());
dict.Add("DeviceIdentifier", Device.Identifier);
dict.Add("DeviceName", Device.Name);
dict.Add("DevicePushToken", Device.PushToken);
}
if(Token != null && Provider.HasValue)
{
dict.Add("TwoFactorToken", Token);
dict.Add("TwoFactorProvider", ((byte)(Provider.Value)).ToString());
dict.Add("TwoFactorRemember", Remember ? "1" : "0");
}
return dict;
}
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Models.Api
{
public class TwoFactorEmailRequest
{
public string Email { get; set; }
public string MasterPasswordHash { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Models.Api
{
public class AttachmentResponse
{
public string Id { get; set; }
public string Url { get; set; }
public string FileName { get; set; }
public string Key { get; set; }
public string Size { get; set; }
public string SizeName { get; set; }
}
}

View File

@@ -1,29 +0,0 @@
using Bit.App.Enums;
using System;
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class CipherResponse
{
public string Id { get; set; }
public string FolderId { get; set; }
public string UserId { get; set; }
public string OrganizationId { get; set; }
public CipherType Type { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }
public IdentityType Identity { get; set; }
public SecureNoteType SecureNote { get; set; }
public IEnumerable<FieldType> Fields { get; set; }
public IEnumerable<AttachmentResponse> Attachments { get; set; }
public IEnumerable<PasswordHistoryResponse> PasswordHistory { get; set; }
public IEnumerable<string> CollectionIds { get; set; }
public DateTime RevisionDate { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Models.Api
{
public class CollectionResponse
{
public string Id { get; set; }
public string Name { get; set; }
public string OrganizationId { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
using Bit.App.Enums;
using System;
namespace Bit.App.Models.Api
{
public class DeviceResponse
{
public string Id { get; set; }
public string Name { get; set; }
public string Identifier { get; set; }
public DeviceType Type { get; set; }
public DateTime CreationDate { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class DomainsResponse
{
public IEnumerable<IEnumerable<string>> EquivalentDomains { get; set; }
public IEnumerable<GlobalDomains> GlobalEquivalentDomains { get; set; }
public class GlobalDomains
{
public byte Type { get; set; }
public IEnumerable<string> Domains { get; set; }
public bool Excluded { get; set; }
}
}
}

View File

@@ -1,14 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class ErrorResponse
{
public string Message { get; set; }
public Dictionary<string, IEnumerable<string>> ValidationErrors { get; set; }
// For use in development environments.
public string ExceptionMessage { get; set; }
public string ExceptionStackTrace { get; set; }
public string InnerExceptionMessage { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using System;
namespace Bit.App.Models.Api
{
public class FolderResponse
{
public string Id { get; set; }
public string Name { get; set; }
public DateTime RevisionDate { get; set; }
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Models.Api
{
public class KeysResponse
{
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class ListResponse<T>
{
public ListResponse(IEnumerable<T> data)
{
Data = data;
}
public IEnumerable<T> Data { get; set; }
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Models.Api
{
public class PasswordHistoryResponse
{
public string Password { get; set; }
public System.DateTime LastUsedDate { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class PreloginResponse
{
public KdfType Kdf { get; set; }
public int KdfIterations { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class ProfileOrganizationResponseModel
{
public string Id { get; set; }
public string Name { get; set; }
public bool UseGroups { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
public bool UseTotp { get; set; }
public bool Use2fa { get; set; }
public bool UsersGetPremium { get; set; }
public int Seats { get; set; }
public int MaxCollections { get; set; }
public short? MaxStorageGb { get; set; }
public string Key { get; set; }
public OrganizationUserStatusType Status { get; set; }
public OrganizationUserType Type { get; set; }
public bool Enabled { get; set; }
}
}

View File

@@ -1,20 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class ProfileResponse
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public bool EmailVerified { get; set; }
public bool Premium { get; set; }
public string MasterPasswordHint { get; set; }
public string Culture { get; set; }
public bool TwoFactorEnabled { get; set; }
public string Key { get; set; }
public string PrivateKey { get; set; }
public string SecurityStamp { get; set; }
public IEnumerable<ProfileOrganizationResponseModel> Organizations { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class SyncResponse
{
public ProfileResponse Profile { get; set; }
public IEnumerable<FolderResponse> Folders { get; set; }
public IEnumerable<CollectionResponse> Collections { get; set; }
public IEnumerable<CipherResponse> Ciphers { get; set; }
public DomainsResponse Domains { get; set; }
}
}

View File

@@ -1,22 +0,0 @@
using Bit.App.Enums;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public class TokenResponse
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public long ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
public Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProviders2 { get; set; }
public string PrivateKey { get; set; }
public string TwoFactorToken { get; set; }
public string Key { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
namespace Bit.App.Models.Api
{
public class SecureNoteType
{
public SecureNoteType() { }
public SecureNoteType(Cipher cipher)
{
Type = cipher.SecureNote.Type;
}
public Enums.SecureNoteType Type { get; set; }
}
}

View File

@@ -1,21 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models
{
public class AppOptions
{
public bool MyVaultTile { get; set; }
public bool FromAutofillFramework { get; set; }
public CipherType? FillType { get; set; }
public string Uri { get; set; }
public CipherType? SaveType { get; set; }
public string SaveName { get; set; }
public string SaveUsername { get; set; }
public string SavePassword { get; set; }
public string SaveCardName { get; set; }
public string SaveCardNumber { get; set; }
public string SaveCardExpMonth { get; set; }
public string SaveCardExpYear { get; set; }
public string SaveCardCode { get; set; }
}
}

View File

@@ -1,49 +0,0 @@
using Bit.App.Models.Api;
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class Attachment
{
public Attachment()
{ }
public Attachment(AttachmentData data)
{
Id = data.Id;
Url = data.Url;
FileName = data.FileName != null ? new CipherString(data.FileName) : null;
Key = data.Key != null ? new CipherString(data.Key) : null;
SetSize(data.Size);
SizeName = data.SizeName;
}
public Attachment(AttachmentResponse response)
{
Id = response.Id;
Url = response.Url;
FileName = response.FileName != null ? new CipherString(response.FileName) : null;
Key = response.Key != null ? new CipherString(response.Key) : null;
SetSize(response.Size);
SizeName = response.SizeName;
}
public string Id { get; set; }
public string Url { get; set; }
public CipherString FileName { get; set; }
public CipherString Key { get; set; }
public long Size { get; set; }
public string SizeName { get; set; }
private void SetSize(string sizeString)
{
long size;
if(!long.TryParse(sizeString, out size))
{
size = 0;
}
Size = size;
}
}
}

View File

@@ -1,43 +0,0 @@
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System;
namespace Bit.App.Models
{
public class Card
{
public Card() { }
public Card(CipherData data)
{
CardDataModel deserializedData;
if(data.Card != null)
{
deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Card);
}
else if(data.Data != null)
{
deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Data);
}
else
{
throw new ArgumentNullException(nameof(data.Card));
}
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; }
}
}

View File

@@ -1,92 +0,0 @@
using Bit.App.Enums;
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));
RevisionDate = data.RevisionDateTime;
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) { }
}
if(!string.IsNullOrWhiteSpace(data.PasswordHistory))
{
try
{
var phModels = JsonConvert.DeserializeObject<IEnumerable<PasswordHistoryDataModel>>(
data.PasswordHistory);
PasswordHistory = phModels?.Select(f => new PasswordHistory(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 IEnumerable<PasswordHistory> PasswordHistory { get; set; }
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public IEnumerable<Attachment> Attachments { get; set; }
public System.DateTime RevisionDate { get; set; }
public Login Login { get; set; }
public Identity Identity { get; set; }
public Card Card { get; set; }
public SecureNote SecureNote { get; set; }
public System.DateTime? PasswordRevisionDisplayDate =>
Login?.Password == null ? null : Login.PasswordRevisionDate;
}
}

View File

@@ -1,135 +0,0 @@
using System;
using Bit.App.Abstractions;
using XLabs.Ioc;
using Bit.App.Enums;
namespace Bit.App.Models
{
public class CipherString
{
private string _decryptedValue;
public CipherString(string encryptedString)
{
if(string.IsNullOrWhiteSpace(encryptedString))
{
throw new ArgumentException(nameof(encryptedString));
}
var headerPieces = encryptedString.Split('.');
string[] encPieces;
EncryptionType encType;
if(headerPieces.Length == 2 && Enum.TryParse(headerPieces[0], out encType))
{
EncryptionType = encType;
encPieces = headerPieces[1].Split('|');
}
else if(headerPieces.Length == 1)
{
encPieces = headerPieces[0].Split('|');
EncryptionType = encPieces.Length == 3 ? EncryptionType.AesCbc128_HmacSha256_B64 : EncryptionType.AesCbc256_B64;
}
else
{
throw new ArgumentException("Malformed header.");
}
switch(EncryptionType)
{
case EncryptionType.AesCbc256_B64:
if(encPieces.Length != 2)
{
throw new ArgumentException("Malformed encPieces.");
}
InitializationVector = encPieces[0];
CipherText = encPieces[1];
break;
case EncryptionType.AesCbc128_HmacSha256_B64:
case EncryptionType.AesCbc256_HmacSha256_B64:
if(encPieces.Length != 3)
{
throw new ArgumentException("Malformed encPieces.");
}
InitializationVector = encPieces[0];
CipherText = encPieces[1];
Mac = encPieces[2];
break;
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_B64:
if(encPieces.Length != 1)
{
throw new ArgumentException("Malformed encPieces.");
}
CipherText = encPieces[0];
break;
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
if(encPieces.Length != 2)
{
throw new ArgumentException("Malformed encPieces.");
}
CipherText = encPieces[0];
Mac = encPieces[1];
break;
default:
throw new ArgumentException("Unknown encType.");
}
EncryptedString = encryptedString;
}
public CipherString(EncryptionType encryptionType, string initializationVector, string cipherText, string mac = null)
{
if(string.IsNullOrWhiteSpace(initializationVector))
{
throw new ArgumentNullException(nameof(initializationVector));
}
if(string.IsNullOrWhiteSpace(cipherText))
{
throw new ArgumentNullException(nameof(cipherText));
}
EncryptionType = encryptionType;
EncryptedString = string.Format("{0}.{1}|{2}", (byte)EncryptionType, initializationVector, cipherText);
if(!string.IsNullOrWhiteSpace(mac))
{
EncryptedString = string.Format("{0}|{1}", EncryptedString, mac);
}
CipherText = cipherText;
InitializationVector = initializationVector;
Mac = mac;
}
public EncryptionType EncryptionType { get; private set; }
public string EncryptedString { get; private set; }
public string InitializationVector { get; private set; }
public string CipherText { get; private set; }
public string Mac { get; private set; }
public byte[] InitializationVectorBytes => string.IsNullOrWhiteSpace(InitializationVector) ?
null : Convert.FromBase64String(InitializationVector);
public byte[] CipherTextBytes => Convert.FromBase64String(CipherText);
public byte[] MacBytes => Mac == null ? null : Convert.FromBase64String(Mac);
public string Decrypt(string orgId = null)
{
if(_decryptedValue == null)
{
var cryptoService = Resolver.Resolve<ICryptoService>();
if(!string.IsNullOrWhiteSpace(orgId))
{
_decryptedValue = cryptoService.Decrypt(this, cryptoService.GetOrgKey(orgId));
}
else
{
_decryptedValue = cryptoService.Decrypt(this);
}
}
return _decryptedValue;
}
}
}

View File

@@ -1,29 +0,0 @@
using Bit.App.Models.Data;
using Bit.App.Models.Api;
namespace Bit.App.Models
{
public class Collection
{
public Collection()
{ }
public Collection(CollectionData data)
{
Id = data.Id;
OrganizationId = data.OrganizationId;
Name = data.Name != null ? new CipherString(data.Name) : null;
}
public Collection(CollectionResponse response)
{
Id = response.Id;
OrganizationId = response.OrganizationId;
Name = response.Name != null ? new CipherString(response.Name) : null;
}
public string Id { get; set; }
public string OrganizationId { get; set; }
public CipherString Name { get; set; }
}
}

View File

@@ -1,51 +0,0 @@
using SQLite;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
[Table("Attachment")]
public class AttachmentData : IDataObject<string>
{
public AttachmentData()
{ }
public AttachmentData(Attachment attachment, string cipherId)
{
Id = attachment.Id;
LoginId = cipherId;
Url = attachment.Url;
FileName = attachment.FileName?.EncryptedString;
Key = attachment.Key?.EncryptedString;
Size = attachment.Size.ToString();
SizeName = attachment.SizeName;
}
public AttachmentData(AttachmentResponse response, string cipherId)
{
Id = response.Id;
LoginId = cipherId;
Url = response.Url;
FileName = response.FileName;
Key = response.Key;
Size = response.Size;
SizeName = response.SizeName;
}
[PrimaryKey]
public string Id { get; set; }
// Really should be called CipherId
[Indexed]
public string LoginId { get; set; }
public string Url { get; set; }
public string FileName { get; set; }
public string Key { get; set; }
public string Size { get; set; }
public string SizeName { get; set; }
public Attachment ToAttachment()
{
return new Attachment(this);
}
}
}

View File

@@ -1,18 +0,0 @@
using SQLite;
namespace Bit.App.Models.Data
{
[Table("CipherCollection")]
public class CipherCollectionData
{
[PrimaryKey]
[AutoIncrement]
public int Id { get; set; }
[Indexed]
public string UserId { get; set; }
[Indexed]
public string CipherId { get; set; }
[Indexed]
public string CollectionId { get; set; }
}
}

View File

@@ -1,102 +0,0 @@
using System;
using SQLite;
using Bit.App.Abstractions;
using Newtonsoft.Json;
using System.Linq;
using Bit.App.Enums;
using Bit.App.Models.Api;
using Newtonsoft.Json.Linq;
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 = null;
switch(cipher.Type)
{
case CipherType.Login:
var loginObj = JObject.FromObject(new LoginDataModel(cipher),
new JsonSerializer { NullValueHandling = NullValueHandling.Ignore });
loginObj[nameof(LoginDataModel.Uri)]?.Parent?.Remove();
Login = loginObj.ToString(Formatting.None);
break;
case CipherType.SecureNote:
var noteData = new SecureNoteDataModel(cipher);
SecureNote = JsonConvert.SerializeObject(noteData);
break;
case CipherType.Card:
var cardData = new CardDataModel(cipher);
Card = JsonConvert.SerializeObject(cardData);
break;
case CipherType.Identity:
var idData = new IdentityDataModel(cipher);
Identity = JsonConvert.SerializeObject(idData);
break;
default:
throw new ArgumentException(nameof(cipher.Type));
}
Name = cipher.Name;
Notes = cipher.Notes;
if(cipher.Fields != null && cipher.Fields.Any())
{
try
{
Fields = JsonConvert.SerializeObject(cipher.Fields.Select(f => new FieldDataModel(f)));
}
catch(JsonSerializationException) { }
}
if(cipher.PasswordHistory != null && cipher.PasswordHistory.Any())
{
try
{
PasswordHistory = JsonConvert.SerializeObject(
cipher.PasswordHistory.Select(h => new PasswordHistoryDataModel(h)));
}
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 string PasswordHistory { get; set; }
public string Login { get; set; }
public string Card { get; set; }
public string Identity { get; set; }
public string SecureNote { 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;
[Obsolete]
public string Data { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
using Bit.App.Models.Api;
using System;
namespace Bit.App.Models.Data
{
public class CardDataModel : CipherDataModel
{
public CardDataModel() { }
public CardDataModel(CipherResponse response)
: base(response)
{
if(response?.Card == null)
{
throw new ArgumentNullException(nameof(response.Card));
}
CardholderName = response.Card.CardholderName;
Brand = response.Card.Brand;
Number = response.Card.Number;
ExpMonth = response.Card.ExpMonth;
ExpYear = response.Card.ExpYear;
Code = response.Card.Code;
}
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; }
}
}

View File

@@ -1,24 +0,0 @@
using Bit.App.Models.Api;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models.Data
{
public abstract class CipherDataModel
{
public CipherDataModel() { }
public CipherDataModel(CipherResponse cipher)
{
Name = cipher.Name;
Notes = cipher.Notes;
Fields = cipher.Fields?.Select(f => new FieldDataModel(f));
PasswordHistory = cipher.PasswordHistory?.Select(h => new PasswordHistoryDataModel(h));
}
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldDataModel> Fields { get; set; }
public IEnumerable<PasswordHistoryDataModel> PasswordHistory { get; set; }
}
}

View File

@@ -1,20 +0,0 @@
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
public class FieldDataModel
{
public FieldDataModel() { }
public FieldDataModel(FieldType f)
{
Type = f.Type;
Name = f.Name;
Value = f.Value;
}
public Enums.FieldType Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@@ -1,57 +0,0 @@
using Bit.App.Models.Api;
using System;
namespace Bit.App.Models.Data
{
public class IdentityDataModel : CipherDataModel
{
public IdentityDataModel() { }
public IdentityDataModel(CipherResponse response)
: base(response)
{
if(response?.Identity == null)
{
throw new ArgumentNullException(nameof(response.Identity));
}
Title = response.Identity.Title;
FirstName = response.Identity.FirstName;
MiddleName = response.Identity.MiddleName;
LastName = response.Identity.LastName;
Address1 = response.Identity.Address1;
Address2 = response.Identity.Address2;
Address3 = response.Identity.Address3;
City = response.Identity.City;
State = response.Identity.State;
PostalCode = response.Identity.PostalCode;
Country = response.Identity.Country;
Company = response.Identity.Company;
Email = response.Identity.Email;
Phone = response.Identity.Phone;
SSN = response.Identity.SSN;
Username = response.Identity.Username;
PassportNumber = response.Identity.PassportNumber;
LicenseNumber = response.Identity.LicenseNumber;
}
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; }
}
}

View File

@@ -1,40 +0,0 @@
using Bit.App.Models.Api;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models.Data
{
public class LoginDataModel : CipherDataModel
{
private string _uri;
public LoginDataModel() { }
public LoginDataModel(CipherResponse response)
: base(response)
{
if(response?.Login == null)
{
throw new ArgumentNullException(nameof(response.Login));
}
Uris = response.Login.Uris?.Where(u => u != null).Select(u => new LoginUriDataModel(u));
Username = response.Login.Username;
Password = response.Login.Password;
PasswordRevisionDate = response.Login.PasswordRevisionDate;
Totp = response.Login.Totp;
}
public string Uri
{
get => Uris?.FirstOrDefault()?.Uri ?? _uri;
set { _uri = value; }
}
public IEnumerable<LoginUriDataModel> Uris { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public DateTime? PasswordRevisionDate { get; set; }
public string Totp { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
public class LoginUriDataModel
{
public LoginUriDataModel() { }
public LoginUriDataModel(LoginUriType u)
{
Uri = u.Uri;
Match = u.Match;
}
public string Uri { get; set; }
public UriMatchType? Match { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
public class PasswordHistoryDataModel
{
public PasswordHistoryDataModel() { }
public PasswordHistoryDataModel(PasswordHistoryResponse h)
{
Password = h.Password;
LastUsedDate = h.LastUsedDate;
}
public string Password { get; set; }
public System.DateTime LastUsedDate { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Bit.App.Models.Api;
using System;
namespace Bit.App.Models.Data
{
public class SecureNoteDataModel : CipherDataModel
{
public SecureNoteDataModel() { }
public SecureNoteDataModel(CipherResponse response)
: base(response)
{
if(response?.SecureNote == null)
{
throw new ArgumentNullException(nameof(response.SecureNote));
}
Type = response.SecureNote.Type;
}
public Enums.SecureNoteType Type { get; set; }
}
}

View File

@@ -1,36 +0,0 @@
using SQLite;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
[Table("Collection")]
public class CollectionData : IDataObject<string>
{
public CollectionData()
{ }
public CollectionData(Collection collection, string userId)
{
Id = collection.Id;
UserId = userId;
Name = collection.Name?.EncryptedString;
OrganizationId = collection.OrganizationId;
}
public CollectionData(CollectionResponse collection, string userId)
{
Id = collection.Id;
UserId = userId;
Name = collection.Name;
OrganizationId = collection.OrganizationId;
}
[PrimaryKey]
public string Id { get; set; }
[Indexed]
public string UserId { get; set; }
public string Name { get; set; }
public string OrganizationId { get; set; }
}
}

View File

@@ -1,36 +0,0 @@
using System;
using SQLite;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
namespace Bit.App.Models.Data
{
[Table("Folder")]
public class FolderData : IDataObject<string>
{
public FolderData()
{ }
public FolderData(Folder folder, string userId)
{
Id = folder.Id;
UserId = userId;
Name = folder.Name?.EncryptedString;
}
public FolderData(FolderResponse folder, string userId)
{
Id = folder.Id;
UserId = userId;
Name = folder.Name;
RevisionDateTime = folder.RevisionDate;
}
[PrimaryKey]
public string Id { get; set; }
[Indexed]
public string UserId { get; set; }
public string Name { get; set; }
public DateTime RevisionDateTime { get; set; } = DateTime.UtcNow;
}
}

View File

@@ -1,16 +0,0 @@
using SQLite;
using Bit.App.Abstractions;
namespace Bit.App.Models.Data
{
[Table("Settings")]
public class SettingsData : IDataObject<string>
{
public SettingsData()
{ }
[PrimaryKey]
public string Id { get; set; }
public string EquivalentDomains { get; set; }
}
}

View File

@@ -1,348 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Bit.App.Models
{
// ref: https://github.com/danesparza/domainname-parser
public class DomainName
{
private const string IpRegex = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
private string _subDomain = string.Empty;
private string _domain = string.Empty;
private string _tld = string.Empty;
private TLDRule _tldRule = null;
public string SubDomain => _subDomain;
public string Domain => _domain;
public string SLD => _domain;
public string TLD => _tld;
public TLDRule Rule => _tldRule;
public string BaseDomain => $"{_domain}.{_tld}";
public DomainName(string TLD, string SLD, string SubDomain, TLDRule TLDRule)
{
_tld = TLD;
_domain = SLD;
_subDomain = SubDomain;
_tldRule = TLDRule;
}
public static bool TryParse(string domainString, out DomainName result)
{
bool retval = false;
// Our temporary domain parts:
var tld = string.Empty;
var sld = string.Empty;
var subdomain = string.Empty;
TLDRule _tldrule = null;
result = null;
try
{
// Try parsing the domain name ... this might throw formatting exceptions
ParseDomainName(domainString, out tld, out sld, out subdomain, out _tldrule);
// Construct a new DomainName object and return it
result = new DomainName(tld, sld, subdomain, _tldrule);
// Return 'true'
retval = true;
}
catch
{
// Looks like something bad happened -- return 'false'
retval = false;
}
return retval;
}
public static bool TryParseBaseDomain(string domainString, out string result)
{
if(Regex.IsMatch(domainString, IpRegex))
{
result = domainString;
return true;
}
DomainName domain;
var retval = TryParse(domainString, out domain);
result = domain?.BaseDomain;
return retval;
}
private static void ParseDomainName(string domainString, out string TLD, out string SLD, out string SubDomain, out TLDRule MatchingRule)
{
// Make sure domain is all lowercase
domainString = domainString.ToLower();
TLD = string.Empty;
SLD = string.Empty;
SubDomain = string.Empty;
MatchingRule = null;
// If the fqdn is empty, we have a problem already
if(domainString.Trim() == string.Empty)
{
throw new ArgumentException("The domain cannot be blank");
}
// Next, find the matching rule:
MatchingRule = FindMatchingTLDRule(domainString);
// At this point, no rules match, we have a problem
if(MatchingRule == null)
{
throw new FormatException("The domain does not have a recognized TLD");
}
// Based on the tld rule found, get the domain (and possibly the subdomain)
var tempSudomainAndDomain = string.Empty;
var tldIndex = 0;
// First, determine what type of rule we have, and set the TLD accordingly
switch(MatchingRule.Type)
{
case TLDRule.RuleType.Normal:
tldIndex = domainString.LastIndexOf("." + MatchingRule.Name);
tempSudomainAndDomain = domainString.Substring(0, tldIndex);
TLD = domainString.Substring(tldIndex + 1);
break;
case TLDRule.RuleType.Wildcard:
// This finds the last portion of the TLD...
tldIndex = domainString.LastIndexOf("." + MatchingRule.Name);
tempSudomainAndDomain = domainString.Substring(0, tldIndex);
// But we need to find the wildcard portion of it:
tldIndex = tempSudomainAndDomain.LastIndexOf(".");
tempSudomainAndDomain = domainString.Substring(0, tldIndex);
TLD = domainString.Substring(tldIndex + 1);
break;
case TLDRule.RuleType.Exception:
tldIndex = domainString.LastIndexOf(".");
tempSudomainAndDomain = domainString.Substring(0, tldIndex);
TLD = domainString.Substring(tldIndex + 1);
break;
}
// See if we have a subdomain:
List<string> lstRemainingParts = new List<string>(tempSudomainAndDomain.Split('.'));
// If we have 0 parts left, there is just a tld and no domain or subdomain
// If we have 1 part, it's the domain, and there is no subdomain
// If we have 2+ parts, the last part is the domain, the other parts (combined) are the subdomain
if(lstRemainingParts.Count > 0)
{
// Set the domain:
SLD = lstRemainingParts[lstRemainingParts.Count - 1];
// Set the subdomain, if there is one to set:
if(lstRemainingParts.Count > 1)
{
// We strip off the trailing period, too
SubDomain = tempSudomainAndDomain.Substring(0, tempSudomainAndDomain.Length - SLD.Length - 1);
}
}
}
private static TLDRule FindMatchingTLDRule(string domainString)
{
// Split our domain into parts (based on the '.')
// ...Put these parts in a list
// ...Make sure these parts are in reverse order (we'll be checking rules from the right-most pat of the domain)
var lstDomainParts = domainString.Split('.').ToList();
lstDomainParts.Reverse();
// Begin building our partial domain to check rules with:
var checkAgainst = string.Empty;
// Our 'matches' collection:
var ruleMatches = new List<TLDRule>();
foreach(string domainPart in lstDomainParts)
{
// Add on our next domain part:
checkAgainst = string.Format("{0}.{1}", domainPart, checkAgainst);
// If we end in a period, strip it off:
if(checkAgainst.EndsWith("."))
{
checkAgainst = checkAgainst.Substring(0, checkAgainst.Length - 1);
}
var rules = Enum.GetValues(typeof(TLDRule.RuleType)).Cast<TLDRule.RuleType>();
foreach(var rule in rules)
{
// Try to match rule:
TLDRule result;
if(TLDRulesCache.Instance.TLDRuleLists[rule].TryGetValue(checkAgainst, out result))
{
ruleMatches.Add(result);
}
//Debug.WriteLine(string.Format("Domain part {0} matched {1} {2} rules", checkAgainst, result == null ? 0 : 1, rule));
}
}
// Sort our matches list (longest rule wins, according to :
var results = from match in ruleMatches
orderby match.Name.Length descending
select match;
// Take the top result (our primary match):
TLDRule primaryMatch = results.Take(1).SingleOrDefault();
if(primaryMatch != null)
{
//Debug.WriteLine(string.Format("Looks like our match is: {0}, which is a(n) {1} rule.", primaryMatch.Name, primaryMatch.Type));
}
else
{
//Debug.WriteLine(string.Format("No rules matched domain: {0}", domainString));
}
return primaryMatch;
}
public class TLDRule : IComparable<TLDRule>
{
public string Name { get; private set; }
public RuleType Type { get; private set; }
public TLDRule(string RuleInfo)
{
// Parse the rule and set properties accordingly:
if(RuleInfo.StartsWith("*"))
{
Type = RuleType.Wildcard;
Name = RuleInfo.Substring(2);
}
else if(RuleInfo.StartsWith("!"))
{
Type = RuleType.Exception;
Name = RuleInfo.Substring(1);
}
else
{
Type = RuleType.Normal;
Name = RuleInfo;
}
}
public int CompareTo(TLDRule other)
{
if(other == null)
{
return -1;
}
return Name.CompareTo(other.Name);
}
public enum RuleType
{
Normal,
Wildcard,
Exception
}
}
public class TLDRulesCache
{
private static volatile TLDRulesCache _uniqueInstance;
private static object _syncObj = new object();
private static object _syncList = new object();
private IDictionary<TLDRule.RuleType, IDictionary<string, TLDRule>> _lstTLDRules;
private TLDRulesCache()
{
// Initialize our internal list:
_lstTLDRules = GetTLDRules();
}
public static TLDRulesCache Instance
{
get
{
if(_uniqueInstance == null)
{
lock(_syncObj)
{
if(_uniqueInstance == null)
{
_uniqueInstance = new TLDRulesCache();
}
}
}
return (_uniqueInstance);
}
}
public IDictionary<TLDRule.RuleType, IDictionary<string, TLDRule>> TLDRuleLists
{
get
{
return _lstTLDRules;
}
set
{
_lstTLDRules = value;
}
}
public static void Reset()
{
lock(_syncObj)
{
_uniqueInstance = null;
}
}
private IDictionary<TLDRule.RuleType, IDictionary<string, TLDRule>> GetTLDRules()
{
var results = new Dictionary<TLDRule.RuleType, IDictionary<string, TLDRule>>();
var rules = Enum.GetValues(typeof(TLDRule.RuleType)).Cast<TLDRule.RuleType>();
foreach(var rule in rules)
{
results[rule] = new Dictionary<string, TLDRule>(StringComparer.CurrentCultureIgnoreCase);
}
var ruleStrings = ReadRulesData();
// Strip out any lines that are:
// a.) A comment
// b.) Blank
foreach(var ruleString in ruleStrings.Where(ruleString => !ruleString.StartsWith("//") && ruleString.Trim().Length != 0))
{
var result = new TLDRule(ruleString);
results[result.Type][result.Name] = result;
}
// Return our results:
Debug.WriteLine(string.Format("Loaded {0} rules into cache.", results.Values.Sum(r => r.Values.Count)));
return results;
}
private IEnumerable<string> ReadRulesData()
{
var assembly = typeof(TLDRulesCache).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream("Bit.App.Resources.public_suffix_list.dat");
string line;
using(var reader = new StreamReader(stream))
{
while((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}
}
}

View File

@@ -1,21 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class Field
{
public Field() { }
public Field(FieldDataModel model)
{
Type = model.Type;
Name = model.Name != null ? new CipherString(model.Name) : null;
Value = model.Value != null ? new CipherString(model.Value) : null;
}
public FieldType Type { get; set; }
public CipherString Name { get; set; }
public CipherString Value { get; set; }
}
}

View File

@@ -1,36 +0,0 @@
using Bit.App.Models.Data;
using Bit.App.Models.Api;
namespace Bit.App.Models
{
public class Folder
{
public Folder()
{ }
public Folder(FolderData data)
{
Id = data.Id;
Name = data.Name != null ? new CipherString(data.Name) : null;
}
public Folder(FolderResponse response)
{
Id = response.Id;
Name = response.Name != null ? new CipherString(response.Name) : null;
}
public string Id { get; set; }
public CipherString Name { get; set; }
public FolderRequest ToFolderRequest()
{
return new FolderRequest(this);
}
public FolderData ToFolderData(string userId)
{
return new FolderData(this, userId);
}
}
}

View File

@@ -1,68 +0,0 @@
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System;
namespace Bit.App.Models
{
public class Identity
{
public Identity() { }
public Identity(CipherData data)
{
IdentityDataModel deserializedData;
if(data.Identity != null)
{
deserializedData = JsonConvert.DeserializeObject<IdentityDataModel>(data.Identity);
}
else if(data.Data != null)
{
deserializedData = JsonConvert.DeserializeObject<IdentityDataModel>(data.Data);
}
else
{
throw new ArgumentNullException(nameof(data.Identity));
}
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; }
}
}

View File

@@ -1,42 +0,0 @@
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models
{
public class Login
{
public Login() { }
public Login(CipherData data)
{
LoginDataModel deserializedData;
if(data.Login != null)
{
deserializedData = JsonConvert.DeserializeObject<LoginDataModel>(data.Login);
}
else if(data.Data != null)
{
deserializedData = JsonConvert.DeserializeObject<LoginDataModel>(data.Data);
}
else
{
throw new ArgumentNullException(nameof(data.Identity));
}
Username = deserializedData.Username != null ? new CipherString(deserializedData.Username) : null;
Password = deserializedData.Password != null ? new CipherString(deserializedData.Password) : null;
PasswordRevisionDate = deserializedData.PasswordRevisionDate;
Totp = deserializedData.Totp != null ? new CipherString(deserializedData.Totp) : null;
Uris = deserializedData.Uris?.Select(u => new LoginUri(u));
}
public IEnumerable<LoginUri> Uris { get; set; }
public CipherString Username { get; set; }
public CipherString Password { get; set; }
public DateTime? PasswordRevisionDate { get; set; }
public CipherString Totp { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using Bit.App.Enums;
using System.Collections.Generic;
namespace Bit.App.Models
{
public class LoginResult
{
public bool Success { get; set; }
public string ErrorMessage { get; set; }
}
public class FullLoginResult : LoginResult
{
public bool TwoFactorRequired => TwoFactorProviders != null && TwoFactorProviders.Count > 0;
public Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProviders { get; set; }
public SymmetricCryptoKey Key { get; set; }
public string MasterPasswordHash { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class LoginUri
{
public LoginUri() { }
public LoginUri(LoginUriDataModel data)
{
Uri = data.Uri != null ? new CipherString(data.Uri) : null;
Match = data.Match;
}
public CipherString Uri { get; set; }
public UriMatchType? Match { get; set; }
}
}

View File

@@ -1,65 +0,0 @@
using Bit.App.Utilities;
using PCLCrypto;
namespace Bit.App.Models
{
public class OtpAuth
{
public OtpAuth(string key)
{
if(key?.ToLowerInvariant().StartsWith("otpauth://") ?? false)
{
var qsParams = Helpers.GetQueryParams(key);
if(qsParams.ContainsKey("digits") && qsParams["digits"] != null &&
int.TryParse(qsParams["digits"].Trim(), out var digitParam))
{
if(digitParam > 10)
{
Digits = 10;
}
else if(digitParam > 0)
{
Digits = digitParam;
}
}
if(qsParams.ContainsKey("period") && qsParams["period"] != null &&
int.TryParse(qsParams["period"].Trim(), out var periodParam) && periodParam > 0)
{
Period = periodParam;
}
if(qsParams.ContainsKey("secret") && qsParams["secret"] != null)
{
Secret = qsParams["secret"];
}
if(qsParams.ContainsKey("algorithm") && qsParams["algorithm"] != null)
{
var algParam = qsParams["algorithm"].ToLowerInvariant();
if(algParam == "sha256")
{
Algorithm = MacAlgorithm.HmacSha256;
}
else if(algParam == "sha512")
{
Algorithm = MacAlgorithm.HmacSha512;
}
}
}
else if (key?.ToLowerInvariant().StartsWith("steam://") ?? false)
{
Steam = true;
Digits = 5;
Secret = key.Substring(8);
}
else
{
Secret = key;
}
}
public int Period { get; set; } = 30;
public int Digits { get; set; } = 6;
public MacAlgorithm Algorithm { get; set; } = MacAlgorithm.HmacSha1;
public string Secret { get; set; }
public bool Steam { get; set; }
}
}

View File

@@ -1,47 +0,0 @@
using System;
using System.ComponentModel;
using Plugin.Settings.Abstractions;
namespace Bit.App.Models.Page
{
public class AppExtensionPageModel : INotifyPropertyChanged
{
private readonly ISettings _settings;
public AppExtensionPageModel(ISettings settings)
{
_settings = settings;
}
public event PropertyChangedEventHandler PropertyChanged;
public bool Started
{
get { return _settings.GetValueOrDefault(Constants.ExtensionStarted, false); }
set
{
_settings.AddOrUpdateValue(Constants.ExtensionStarted, true);
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Started)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(NotStarted)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(StartedAndNotActivated)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(StartedAndActivated)));
}
}
public bool Activated
{
get { return _settings.GetValueOrDefault(Constants.ExtensionActivated, false); }
set
{
_settings.AddOrUpdateValue(Constants.ExtensionActivated, value);
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Activated)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(StartedAndNotActivated)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(StartedAndActivated)));
}
}
public bool NotStarted => !Started;
public bool StartedAndNotActivated => Started && !Activated;
public bool StartedAndActivated => Started && Activated;
}
}

View File

@@ -1,40 +0,0 @@
using System;
using System.ComponentModel;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Models.Page
{
public class PasswordGeneratorPageModel : INotifyPropertyChanged
{
private string _password = " ";
private string _length;
public PasswordGeneratorPageModel() { }
public event PropertyChangedEventHandler PropertyChanged;
public string Password
{
get { return _password; }
set
{
_password = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Password)));
// PropertyChanged(this, new PropertyChangedEventArgs(nameof(FormattedPassword)));
}
}
public FormattedString FormattedPassword => PasswordFormatter.FormatPassword(_password);
public string Length
{
get { return _length; }
set
{
_length = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Length)));
}
}
}
}

View File

@@ -1,36 +0,0 @@
using System.ComponentModel;
namespace Bit.App.Models.Page
{
public class PinPageModel : INotifyPropertyChanged
{
private string _pin = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
public string LabelText
{
get
{
var newText = string.Empty;
for(int i = 0; i < 4; i++)
{
newText += _pin.Length <= i ? "- " : "• ";
}
return newText.TrimEnd();
}
}
public string PIN
{
get { return _pin; }
set
{
_pin = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(PIN)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LabelText)));
}
}
}
}

View File

@@ -1,14 +0,0 @@
namespace Bit.App.Models.Page
{
public class SettingsFolderPageModel
{
public SettingsFolderPageModel(Folder folder)
{
Id = folder.Id;
Name = folder.Name?.Decrypt();
}
public string Id { get; set; }
public string Name { get; set; }
}
}

View File

@@ -1,25 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Page
{
public class VaultAttachmentsPageModel
{
public class Attachment : List<Attachment>
{
public string Id { get; set; }
public string Name { get; set; }
public string SizeName { get; set; }
public long Size { get; set; }
public string Url { get; set; }
public Attachment(Models.Attachment attachment, string orgId)
{
Id = attachment.Id;
Name = attachment.FileName?.Decrypt(orgId);
SizeName = attachment.SizeName;
Size = attachment.Size;
Url = attachment.Url;
}
}
}
}

View File

@@ -1,245 +0,0 @@
using System;
using System.Collections.Generic;
using Bit.App.Resources;
using System.Linq;
using Bit.App.Enums;
using Bit.App.Abstractions;
namespace Bit.App.Models.Page
{
public class VaultListPageModel
{
public class Cipher
{
public Cipher(Models.Cipher cipher, IAppSettingsService appSettings)
{
CipherModel = cipher;
Id = cipher.Id;
Shared = !string.IsNullOrWhiteSpace(cipher.OrganizationId);
HasAttachments = cipher.Attachments?.Any() ?? false;
FolderId = cipher.FolderId;
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
Type = cipher.Type;
if(string.IsNullOrWhiteSpace(Name) || Name.Length == 0)
{
NameGroup = "-";
}
else if(Char.IsLetter(Name[0]))
{
NameGroup = Name[0].ToString();
}
else if(Char.IsDigit(Name[0]))
{
NameGroup = "#";
}
else
{
NameGroup = "-";
}
switch(cipher.Type)
{
case CipherType.Login:
LoginUsername = cipher.Login?.Username?.Decrypt(cipher.OrganizationId) ?? " ";
LoginUri = cipher.Login.Uris?.FirstOrDefault()?.Uri?.Decrypt(cipher.OrganizationId) ?? " ";
LoginPassword = new Lazy<string>(() => cipher.Login?.Password?.Decrypt(cipher.OrganizationId));
LoginTotp = new Lazy<string>(() => cipher.Login?.Totp?.Decrypt(cipher.OrganizationId));
Icon = "login.png";
var hostnameUri = LoginUri;
var isWebsite = false;
var imageEnabled = !appSettings.DisableWebsiteIcons;
if(hostnameUri.StartsWith("androidapp://"))
{
Icon = "android.png";
}
else if(hostnameUri.StartsWith("iosapp://"))
{
Icon = "apple.png";
}
else if(imageEnabled && !hostnameUri.Contains("://") && hostnameUri.Contains("."))
{
hostnameUri = $"http://{hostnameUri}";
isWebsite = true;
}
else if(imageEnabled)
{
isWebsite = hostnameUri.StartsWith("http") && hostnameUri.Contains(".");
}
if(imageEnabled && isWebsite && Uri.TryCreate(hostnameUri, UriKind.Absolute, out Uri u))
{
var iconsUrl = appSettings.IconsUrl;
if(string.IsNullOrWhiteSpace(iconsUrl))
{
if(!string.IsNullOrWhiteSpace(appSettings.BaseUrl))
{
iconsUrl = $"{appSettings.BaseUrl}/icons";
}
else
{
iconsUrl = "https://icons.bitwarden.net";
}
}
Icon = $"{iconsUrl}/{u.Host}/icon.png";
}
Subtitle = LoginUsername;
break;
case CipherType.SecureNote:
Icon = "note.png";
Subtitle = " ";
break;
case CipherType.Card:
CardNumber = cipher.Card?.Number?.Decrypt(cipher.OrganizationId) ?? " ";
var cardBrand = cipher.Card?.Brand?.Decrypt(cipher.OrganizationId) ?? " ";
CardCode = new Lazy<string>(() => cipher.Card?.Code?.Decrypt(cipher.OrganizationId));
Icon = "card.png";
Subtitle = cardBrand;
if(!string.IsNullOrWhiteSpace(CardNumber) && CardNumber.Length >= 4)
{
if(!string.IsNullOrWhiteSpace(CardNumber))
{
Subtitle += ", ";
}
Subtitle += ("*" + CardNumber.Substring(CardNumber.Length - 4));
}
break;
case CipherType.Identity:
var firstName = cipher.Identity?.FirstName?.Decrypt(cipher.OrganizationId) ?? " ";
var lastName = cipher.Identity?.LastName?.Decrypt(cipher.OrganizationId) ?? " ";
Icon = "id.png";
Subtitle = " ";
if(!string.IsNullOrWhiteSpace(firstName))
{
Subtitle = firstName;
}
if(!string.IsNullOrWhiteSpace(lastName))
{
if(!string.IsNullOrWhiteSpace(Subtitle))
{
Subtitle += " ";
}
Subtitle += lastName;
}
break;
default:
break;
}
}
public Models.Cipher CipherModel { get; set; }
public string Id { get; set; }
public bool Shared { get; set; }
public bool HasAttachments { get; set; }
public string FolderId { get; set; }
public string NameGroup { get; set; }
public string Name { get; set; }
public string Subtitle { get; set; }
public CipherType Type { get; set; }
public string Icon { get; set; }
public string Image { get; set; }
// Login metadata
public string LoginUsername { get; set; }
public Lazy<string> LoginPassword { get; set; }
public string LoginUri { get; set; }
public Lazy<string> LoginTotp { get; set; }
// Login metadata
public string CardNumber { get; set; }
public Lazy<string> CardCode { get; set; }
}
public class AutofillCipher : Cipher
{
public AutofillCipher(Models.Cipher cipher, IAppSettingsService appSettings, bool fuzzy = false)
: base(cipher, appSettings)
{
Fuzzy = fuzzy;
}
public bool Fuzzy { get; set; }
}
public class Section<T> : List<T>
{
public Section(List<T> groupItems, string name, bool doUpper = true)
{
AddRange(groupItems);
if(string.IsNullOrWhiteSpace(name))
{
Name = "-";
}
else if(doUpper)
{
Name = name.ToUpperInvariant();
}
else
{
Name = name;
}
}
public string Name { get; set; }
public string NameShort => string.IsNullOrWhiteSpace(Name) || Name.Length == 0 ? "-" : Name[0].ToString();
}
public class GroupingOrCipher
{
public GroupingOrCipher(TreeNode<Grouping> grouping)
{
Grouping = grouping;
Cipher = null;
}
public GroupingOrCipher(Cipher cipher)
{
Cipher = cipher;
Grouping = null;
}
public TreeNode<Grouping> Grouping { get; set; }
public Cipher Cipher { get; set; }
}
public class Grouping : ITreeNodeObject
{
public Grouping(string name, int count)
{
Id = null;
Name = name;
Folder = true;
Count = count;
}
public Grouping(Folder folder, int? count)
{
Id = folder.Id;
Name = folder.Name?.Decrypt();
Folder = true;
Count = count;
}
public Grouping(Collection collection, int? count)
{
Id = collection.Id;
Name = collection.Name?.Decrypt(collection.OrganizationId);
Collection = true;
Count = count;
}
public string Id { get; set; }
public string Name { get; set; } = AppResources.FolderNone;
public int? Count { get; set; }
public bool Folder { get; set; }
public bool Collection { get; set; }
public bool ShowCount => Count.HasValue;
}
}
}

View File

@@ -1,750 +0,0 @@
using System;
using System.ComponentModel;
using Xamarin.Forms;
using System.Collections.Generic;
using Bit.App.Enums;
using Bit.App.Resources;
using Bit.App.Utilities;
namespace Bit.App.Models.Page
{
public class VaultViewCipherPageModel : INotifyPropertyChanged
{
private const string MaskedPasswordString = "••••••••";
private string _name, _notes, _reivisonDate, _passwordReivisonDate;
private List<Attachment> _attachments;
private List<Field> _fields;
private List<LoginUri> _loginUris;
// Login
private string _loginUsername, _loginPassword, _loginTotpCode;
private int _loginTotpSec = 30;
private bool _loginRevealPassword;
// Card
private string _cardName, _cardNumber, _cardBrand, _cardExpMonth, _cardExpYear, _cardCode;
private bool _cardRevealCardCode;
// Identity
private string _idFirstName, _idLastName, _idMiddleName, _idCompany, _idEmail, _idPhone, _idUsername,
_idPassportNumber, _idLicenseNumber, _idSsn, _idAddress1, _idAddress2, _idAddress3, _idCity,
_idState, _idCountry, _idPostalCode, _idTitle;
public VaultViewCipherPageModel() { }
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get => _name;
set
{
_name = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
public string RevisionDate
{
get => _reivisonDate;
set
{
_reivisonDate = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(RevisionDate)));
}
}
public string PasswordRevisionDate
{
get => _passwordReivisonDate;
set
{
_passwordReivisonDate = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(PasswordRevisionDate)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowPasswordRevisionDate)));
}
}
public bool ShowPasswordRevisionDate => !string.IsNullOrWhiteSpace(PasswordRevisionDate);
public string Notes
{
get => _notes;
set
{
_notes = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Notes)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowNotes)));
}
}
public bool ShowNotes => !string.IsNullOrWhiteSpace(Notes);
public List<Attachment> Attachments
{
get => _attachments;
set
{
_attachments = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Attachments)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowAttachments)));
}
}
public bool ShowAttachments => (Attachments?.Count ?? 0) > 0;
public List<Field> Fields
{
get => _fields;
set
{
_fields = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Fields)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowFields)));
}
}
public bool ShowFields => (Fields?.Count ?? 0) > 0;
// Login
public string LoginUsername
{
get => _loginUsername;
set
{
_loginUsername = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginUsername)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowLoginUsername)));
}
}
public bool ShowLoginUsername => !string.IsNullOrWhiteSpace(LoginUsername);
public string LoginPassword
{
get => _loginPassword;
set
{
_loginPassword = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginPassword)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(FormattedLoginPassword)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowLoginPassword)));
}
}
public bool ShowLoginPassword => !string.IsNullOrWhiteSpace(LoginPassword);
public bool RevealLoginPassword
{
get => _loginRevealPassword;
set
{
_loginRevealPassword = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(RevealLoginPassword)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(FormattedLoginPassword)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginShowHideImage)));
}
}
public FormattedString FormattedLoginPassword => RevealLoginPassword ?
PasswordFormatter.FormatPassword(LoginPassword) : LoginPassword == null ? null : MaskedPasswordString;
public ImageSource LoginShowHideImage => RevealLoginPassword ?
ImageSource.FromFile("eye_slash.png") : ImageSource.FromFile("eye.png");
public List<LoginUri> LoginUris
{
get => _loginUris;
set
{
_loginUris = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginUris)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowLoginUris)));
}
}
public bool ShowLoginUris => (LoginUris?.Count ?? 0) > 0;
public string LoginTotpCode
{
get => _loginTotpCode;
set
{
_loginTotpCode = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginTotpCode)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginTotpCodeFormatted)));
}
}
public int LoginTotpSecond
{
get => _loginTotpSec;
set
{
_loginTotpSec = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginTotpSecond)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(LoginTotpColor)));
}
}
public bool LoginTotpLow => LoginTotpSecond <= 7;
public Color LoginTotpColor => !string.IsNullOrWhiteSpace(LoginTotpCode) && LoginTotpLow ?
Color.Red : Color.Black;
public string LoginTotpCodeFormatted
{
get
{
if(string.IsNullOrWhiteSpace(LoginTotpCode) || LoginTotpCode.Length < 5)
{
return LoginTotpCode;
}
var half = (int)Math.Floor((double)LoginTotpCode.Length / 2);
return string.Format("{0} {1}", LoginTotpCode.Substring(0, half), LoginTotpCode.Substring(half));
}
}
// Card
public string CardName
{
get => _cardName;
set
{
_cardName = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardName)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardName)));
}
}
public bool ShowCardName => !string.IsNullOrWhiteSpace(CardName);
public string CardNumber
{
get => _cardNumber;
set
{
_cardNumber = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardNumber)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardNumber)));
}
}
public bool ShowCardNumber => !string.IsNullOrWhiteSpace(CardNumber);
public string CardBrand
{
get => _cardBrand;
set
{
_cardBrand = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardBrand)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardBrand)));
}
}
public bool ShowCardBrand => !string.IsNullOrWhiteSpace(CardBrand);
public string CardExpMonth
{
private get => _cardExpMonth;
set
{
_cardExpMonth = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardExpMonth)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardExp)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardExp)));
}
}
public string CardExpYear
{
private get => _cardExpYear;
set
{
_cardExpYear = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardExpYear)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardExp)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardExp)));
}
}
public string CardExp
{
get
{
var expMonth = !string.IsNullOrWhiteSpace(CardExpMonth) ? CardExpMonth.PadLeft(2, '0') : "__";
var expYear = "____";
if(!string.IsNullOrWhiteSpace(CardExpYear))
{
expYear = CardExpYear;
}
if(expYear.Length == 2)
{
expYear = "20" + expYear;
}
return $"{expMonth} / {expYear}";
}
}
public bool ShowCardExp => !string.IsNullOrWhiteSpace(CardExpMonth) && !string.IsNullOrWhiteSpace(CardExpYear);
public string CardCode
{
get => _cardCode;
set
{
_cardCode = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardCode)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowCardCode)));
}
}
public bool ShowCardCode => !string.IsNullOrWhiteSpace(CardCode);
public bool RevealCardCode
{
get => _cardRevealCardCode;
set
{
_cardRevealCardCode = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(RevealCardCode)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(MaskedCardCode)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(CardCodeShowHideImage)));
}
}
public string MaskedCardCode => RevealCardCode ?
CardCode : CardCode == null ? null : new String('•', CardCode.Length);
public ImageSource CardCodeShowHideImage => RevealCardCode ?
ImageSource.FromFile("eye_slash.png") : ImageSource.FromFile("eye.png");
// Identity
public string IdTitle
{
get => _idTitle;
set
{
_idTitle = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdTitle)));
}
}
public string IdFirstName
{
private get => _idFirstName;
set
{
_idFirstName = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdFirstName)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdName)));
}
}
public string IdMiddleName
{
private get => _idMiddleName;
set
{
_idMiddleName = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdMiddleName)));
}
}
public string IdLastName
{
private get => _idLastName;
set
{
_idLastName = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdLastName)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdName)));
}
}
public string IdName
{
get
{
var name = IdTitle;
if(!string.IsNullOrWhiteSpace(IdFirstName))
{
name += ((!string.IsNullOrWhiteSpace(name) ? " " : string.Empty) + IdFirstName);
}
if(!string.IsNullOrWhiteSpace(IdMiddleName))
{
name += ((!string.IsNullOrWhiteSpace(name) ? " " : string.Empty) + IdMiddleName);
}
if(!string.IsNullOrWhiteSpace(IdLastName))
{
name += ((!string.IsNullOrWhiteSpace(name) ? " " : string.Empty) + IdLastName);
}
return name;
}
}
public bool ShowIdName => !string.IsNullOrWhiteSpace(IdFirstName) || !string.IsNullOrWhiteSpace(IdLastName);
public string IdUsername
{
get => _idUsername;
set
{
_idUsername = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdUsername)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdUsername)));
}
}
public bool ShowIdUsername => !string.IsNullOrWhiteSpace(IdUsername);
public string IdCompany
{
get => _idCompany;
set
{
_idCompany = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdCompany)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdCompany)));
}
}
public bool ShowIdCompany => !string.IsNullOrWhiteSpace(IdCompany);
public string IdSsn
{
get => _idSsn;
set
{
_idSsn = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdSsn)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdSsn)));
}
}
public bool ShowIdSsn => !string.IsNullOrWhiteSpace(IdSsn);
public string IdPassportNumber
{
get => _idPassportNumber;
set
{
_idPassportNumber = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdPassportNumber)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdPassportNumber)));
}
}
public bool ShowIdPassportNumber => !string.IsNullOrWhiteSpace(IdPassportNumber);
public string IdLicenseNumber
{
get => _idLicenseNumber;
set
{
_idLicenseNumber = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdLicenseNumber)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdLicenseNumber)));
}
}
public bool ShowIdLicenseNumber => !string.IsNullOrWhiteSpace(IdLicenseNumber);
public string IdEmail
{
get => _idEmail;
set
{
_idEmail = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdEmail)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdEmail)));
}
}
public bool ShowIdEmail => !string.IsNullOrWhiteSpace(IdEmail);
public string IdPhone
{
get => _idPhone;
set
{
_idPhone = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdPhone)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdPhone)));
}
}
public bool ShowIdPhone => !string.IsNullOrWhiteSpace(IdPhone);
public string IdAddress1
{
get => _idAddress1;
set
{
_idAddress1 = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress1)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdAddress)));
}
}
public string IdAddress2
{
get => _idAddress2;
set
{
_idAddress2 = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress2)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
}
}
public string IdAddress3
{
get => _idAddress3;
set
{
_idAddress3 = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress3)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
}
}
public string IdCity
{
get => _idCity;
set
{
_idCity = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdCity)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdAddress)));
}
}
public string IdState
{
get => _idState;
set
{
_idState = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdState)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
}
}
public string IdPostalCode
{
get => _idPostalCode;
set
{
_idPostalCode = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdPostalCode)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
}
}
public string IdCountry
{
get => _idCountry;
set
{
_idCountry = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdCountry)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(IdAddress)));
PropertyChanged(this, new PropertyChangedEventArgs(nameof(ShowIdAddress)));
}
}
public string IdAddress
{
get
{
var address = IdAddress1;
if(!string.IsNullOrWhiteSpace(IdAddress2))
{
address += ((!string.IsNullOrWhiteSpace(address) ? "\n" : string.Empty) + IdAddress2);
}
if(!string.IsNullOrWhiteSpace(IdAddress3))
{
address += ((!string.IsNullOrWhiteSpace(address) ? "\n" : string.Empty) + IdAddress3);
}
if(!string.IsNullOrWhiteSpace(IdCity) || !string.IsNullOrWhiteSpace(IdState) ||
!string.IsNullOrWhiteSpace(IdPostalCode))
{
var cityLine = IdCity + ", ";
cityLine += !string.IsNullOrWhiteSpace(IdState) ? IdState : "-";
cityLine += " ";
cityLine += !string.IsNullOrWhiteSpace(IdPostalCode) ? IdPostalCode : "-";
address += ((!string.IsNullOrWhiteSpace(address) ? "\n" : string.Empty) + cityLine);
}
if(!string.IsNullOrWhiteSpace(IdCountry))
{
address += ((!string.IsNullOrWhiteSpace(address) ? "\n" : string.Empty) + IdCountry);
}
return address;
}
}
public bool ShowIdAddress => !string.IsNullOrWhiteSpace(IdAddress1) || !string.IsNullOrWhiteSpace(IdCity) ||
!string.IsNullOrWhiteSpace(IdCountry);
public void Update(Cipher cipher)
{
Name = cipher.Name?.Decrypt(cipher.OrganizationId);
Notes = cipher.Notes?.Decrypt(cipher.OrganizationId);
var revisionDate = DateTime.SpecifyKind(cipher.RevisionDate, DateTimeKind.Utc).ToLocalTime();
RevisionDate = revisionDate.ToShortDateString() + " " + revisionDate.ToShortTimeString();
if(cipher.PasswordRevisionDisplayDate.HasValue)
{
var passwordRevisionDate = DateTime.SpecifyKind(
cipher.PasswordRevisionDisplayDate.Value, DateTimeKind.Utc).ToLocalTime();
PasswordRevisionDate = passwordRevisionDate.ToShortDateString() + " " +
passwordRevisionDate.ToShortTimeString();
}
else
{
PasswordRevisionDate = null;
}
if(cipher.Attachments != null)
{
var attachments = new List<Attachment>();
foreach(var attachment in cipher.Attachments)
{
attachments.Add(new Attachment
{
Id = attachment.Id,
Name = attachment.FileName?.Decrypt(cipher.OrganizationId),
Key = attachment.Key,
SizeName = attachment.SizeName,
Size = attachment.Size,
Url = attachment.Url
});
}
Attachments = attachments;
}
else
{
cipher.Attachments = null;
}
if(cipher.Fields != null)
{
var fields = new List<Field>();
foreach(var field in cipher.Fields)
{
fields.Add(new Field
{
Name = field.Name?.Decrypt(cipher.OrganizationId),
Value = field.Value?.Decrypt(cipher.OrganizationId),
Type = field.Type
});
}
Fields = fields;
}
else
{
Fields = null;
}
switch(cipher.Type)
{
case CipherType.Login:
LoginUsername = cipher.Login.Username?.Decrypt(cipher.OrganizationId);
LoginPassword = cipher.Login.Password?.Decrypt(cipher.OrganizationId);
if(cipher.Login.Uris != null)
{
var uris = new List<LoginUri>();
foreach(var uri in cipher.Login.Uris)
{
uris.Add(new LoginUri
{
Value = uri.Uri?.Decrypt(cipher.OrganizationId)
});
}
LoginUris = uris;
}
else
{
LoginUris = null;
}
break;
case CipherType.Card:
CardName = cipher.Card.CardholderName?.Decrypt(cipher.OrganizationId);
CardNumber = cipher.Card.Number?.Decrypt(cipher.OrganizationId);
CardBrand = cipher.Card.Brand?.Decrypt(cipher.OrganizationId);
CardExpMonth = cipher.Card.ExpMonth?.Decrypt(cipher.OrganizationId);
CardExpYear = cipher.Card.ExpYear?.Decrypt(cipher.OrganizationId);
CardCode = cipher.Card.Code?.Decrypt(cipher.OrganizationId);
break;
case CipherType.Identity:
IdTitle = cipher.Identity.Title?.Decrypt(cipher.OrganizationId);
IdFirstName = cipher.Identity.FirstName?.Decrypt(cipher.OrganizationId);
IdMiddleName = cipher.Identity.MiddleName?.Decrypt(cipher.OrganizationId);
IdLastName = cipher.Identity.LastName?.Decrypt(cipher.OrganizationId);
IdCompany = cipher.Identity.Company?.Decrypt(cipher.OrganizationId);
IdUsername = cipher.Identity.Username?.Decrypt(cipher.OrganizationId);
IdSsn = cipher.Identity.SSN?.Decrypt(cipher.OrganizationId);
IdPassportNumber = cipher.Identity.PassportNumber?.Decrypt(cipher.OrganizationId);
IdLicenseNumber = cipher.Identity.LicenseNumber?.Decrypt(cipher.OrganizationId);
IdEmail = cipher.Identity.Email?.Decrypt(cipher.OrganizationId);
IdPhone = cipher.Identity.Phone?.Decrypt(cipher.OrganizationId);
IdAddress1 = cipher.Identity.Address1?.Decrypt(cipher.OrganizationId);
IdAddress2 = cipher.Identity.Address2?.Decrypt(cipher.OrganizationId);
IdAddress3 = cipher.Identity.Address3?.Decrypt(cipher.OrganizationId);
IdCity = cipher.Identity.City?.Decrypt(cipher.OrganizationId);
IdState = cipher.Identity.State?.Decrypt(cipher.OrganizationId);
IdPostalCode = cipher.Identity.PostalCode?.Decrypt(cipher.OrganizationId);
IdCountry = cipher.Identity.Country?.Decrypt(cipher.OrganizationId);
break;
default:
break;
}
}
public class Attachment
{
public string Id { get; set; }
public string Name { get; set; }
public CipherString Key { get; set; }
public string SizeName { get; set; }
public long Size { get; set; }
public string Url { get; set; }
}
public class Field
{
private string _maskedValue;
public string Name { get; set; }
public string Value { get; set; }
public string MaskedValue => MaskedPasswordString;
public FieldType Type { get; set; }
public bool Revealed { get; set; }
}
public class LoginUri
{
public string Value { get; set; }
public bool ShowLaunch
{
get
{
if(string.IsNullOrWhiteSpace(Value))
{
return false;
}
if(Device.RuntimePlatform == Device.Android && !IsWebsite && !IsApp)
{
return false;
}
if(Device.RuntimePlatform != Device.Android && !IsWebsite)
{
return false;
}
if(!Uri.TryCreate(Value, UriKind.Absolute, out Uri uri))
{
return false;
}
return true;
}
}
public string Host
{
get
{
if(string.IsNullOrWhiteSpace(Value))
{
return null;
}
if(!Uri.TryCreate(Value, UriKind.Absolute, out Uri uri))
{
return Value;
}
if(DomainName.TryParseBaseDomain(uri.Host, out string domain))
{
return domain;
}
return uri.Host;
}
}
public string Label => IsWebsite ? AppResources.Website : AppResources.URI;
public bool IsWebsite => Value == null ? false :
Value.StartsWith("http://") || Value.StartsWith("https://");
public bool IsApp => Value == null ? false : Value.StartsWith(Constants.AndroidAppProtocol);
}
}
}

View File

@@ -1,18 +0,0 @@
using Bit.App.Models.Data;
namespace Bit.App.Models
{
public class PasswordHistory
{
public PasswordHistory() { }
public PasswordHistory(PasswordHistoryDataModel model)
{
Password = model.Password != null ? new CipherString(model.Password) : null;
LastUsedDate = model.LastUsedDate;
}
public CipherString Password { get; set; }
public System.DateTime LastUsedDate { get; set; }
}
}

View File

@@ -1,43 +0,0 @@
using System;
namespace Bit.App.Models
{
/// <summary>
/// Helper class for splitting locales like
/// iOS: ms_MY, gsw_CH
/// Android: in-ID
/// into parts so we can create a .NET culture (or fallback culture)
/// </summary>
public class PlatformCulture
{
public PlatformCulture(string platformCultureString)
{
if(string.IsNullOrWhiteSpace(platformCultureString))
{
throw new ArgumentException("Expected culture identifier", nameof(platformCultureString));
}
// .NET expects dash, not underscore
PlatformString = platformCultureString.Replace("_", "-");
var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
if(dashIndex > 0)
{
var parts = PlatformString.Split('-');
LanguageCode = parts[0];
LocaleCode = parts[1];
}
else
{
LanguageCode = PlatformString;
LocaleCode = "";
}
}
public string PlatformString { get; private set; }
public string LanguageCode { get; private set; }
public string LocaleCode { get; private set; }
public override string ToString()
{
return PlatformString;
}
}
}

View File

@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using Bit.App.Enums;
namespace Bit.App.Models
{
public class PushNotificationData
{
public PushType Type { get; set; }
}
public class PushNotificationDataPayload : PushNotificationData
{
public string Payload { get; set; }
}
public class SyncCipherPushNotification
{
public string Id { get; set; }
public string UserId { get; set; }
public string OrganizationId { get; set; }
public List<Guid> CollectionIds { get; set; }
public DateTime RevisionDate { get; set; }
}
public class SyncFolderPushNotification
{
public string Id { get; set; }
public string UserId { get; set; }
public DateTime RevisionDate { get; set; }
}
public class UserPushNotification
{
public string UserId { get; set; }
public DateTime Date { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System;
namespace Bit.App.Models
{
public class SecureNote
{
public SecureNote() { }
public SecureNote(CipherData data)
{
SecureNoteDataModel deserializedData;
if(data.SecureNote != null)
{
deserializedData = JsonConvert.DeserializeObject<SecureNoteDataModel>(data.SecureNote);
}
else if(data.Data != null)
{
deserializedData = JsonConvert.DeserializeObject<SecureNoteDataModel>(data.Data);
}
else
{
throw new ArgumentNullException(nameof(data.Identity));
}
Type = deserializedData.Type;
}
public SecureNoteType Type { get; set; }
}
}

View File

@@ -1,62 +0,0 @@
using Bit.App.Enums;
using System;
using System.Linq;
namespace Bit.App.Models
{
public class SymmetricCryptoKey
{
public SymmetricCryptoKey(byte[] rawBytes, EncryptionType? encType = null)
{
if(rawBytes == null || rawBytes.Length == 0)
{
throw new Exception("Must provide keyBytes.");
}
if(encType == null)
{
if(rawBytes.Length == 32)
{
encType = EncryptionType.AesCbc256_B64;
}
else if(rawBytes.Length == 64)
{
encType = EncryptionType.AesCbc256_HmacSha256_B64;
}
else
{
throw new Exception("Unable to determine encType.");
}
}
EncryptionType = encType.Value;
Key = rawBytes;
if(EncryptionType == EncryptionType.AesCbc256_B64 && Key.Length == 32)
{
EncKey = Key;
MacKey = null;
}
else if(EncryptionType == EncryptionType.AesCbc128_HmacSha256_B64 && Key.Length == 32)
{
EncKey = Key.Take(16).ToArray();
MacKey = Key.Skip(16).Take(16).ToArray();
}
else if(EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64 && Key.Length == 64)
{
EncKey = Key.Take(32).ToArray();
MacKey = Key.Skip(32).Take(32).ToArray();
}
else
{
throw new Exception("Unsupported encType/key length.");
}
}
public byte[] Key { get; set; }
public string B64Key => Convert.ToBase64String(Key);
public byte[] EncKey { get; set; }
public byte[] MacKey { get; set; }
public EncryptionType EncryptionType { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using Bit.App.Abstractions;
using System.Collections.Generic;
namespace Bit.App.Models
{
public class TreeNode<T> where T : ITreeNodeObject
{
public TreeNode(T node, string name, T parent)
{
Parent = parent;
Node = node;
Node.Name = name;
}
public T Parent { get; set; }
public T Node { get; set; }
public List<TreeNode<T>> Children { get; set; } = new List<TreeNode<T>>();
}
}