1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-28 06:03:40 +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;
namespace Bit.App.Abstractions
{
public interface IDataObject<T> where T : IEquatable<T>
{
T Id { get; }
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Abstractions
{
public interface ITreeNodeObject
{
string Id { get; set; }
string Name { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Api;
using System;
namespace Bit.App.Abstractions
{
public interface IAccountsApiRepository
{
Task<ApiResult<PreloginResponse>> PostPreloginAsync(PreloginRequest requestObj);
Task<ApiResult> PostRegisterAsync(RegisterRequest requestObj);
Task<ApiResult> PostPasswordHintAsync(PasswordHintRequest requestObj);
Task<ApiResult<DateTime?>> GetAccountRevisionDateAsync();
Task<ApiResult<ProfileResponse>> GetProfileAsync();
}
}

View File

@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface IApiRepository<TRequest, TResponse, TId>
where TRequest : class
where TResponse : class
where TId : IEquatable<TId>
{
Task<ApiResult<TResponse>> GetByIdAsync(TId id);
Task<ApiResult<ListResponse<TResponse>>> GetAsync();
Task<ApiResult<TResponse>> PostAsync(TRequest requestObj);
Task<ApiResult<TResponse>> PutAsync(TId id, TRequest requestObj);
Task<ApiResult> DeleteAsync(TId id);
}
}

View File

@@ -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 IAttachmentRepository : IRepository<AttachmentData, string>
{
Task<IEnumerable<AttachmentData>> GetAllByCipherIdAsync(string cipherId);
Task<IEnumerable<AttachmentData>> GetAllByUserIdAsync(string userId);
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface ICipherApiRepository : IApiRepository<CipherRequest, CipherResponse, string>
{
Task<ApiResult<CipherResponse>> PostAttachmentAsync(string cipherId, byte[] data, string key, string fileName);
Task<ApiResult> DeleteAttachmentAsync(string cipherId, string attachmentId);
}
}

View File

@@ -1,15 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Data;
using System.Collections.Generic;
namespace Bit.App.Abstractions
{
public interface ICipherCollectionRepository
{
Task<IEnumerable<CipherCollectionData>> GetAllByUserIdAsync(string userId);
Task<IEnumerable<CipherCollectionData>> GetAllByUserIdCollectionAsync(string userId, string collectionId);
Task InsertAsync(CipherCollectionData obj);
Task DeleteAsync(CipherCollectionData obj);
Task DeleteByUserIdAsync(string userId);
}
}

View File

@@ -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 ICipherRepository : IRepository<CipherData, string>
{
Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId);
Task<IEnumerable<CipherData>> GetAllByUserIdAsync(string userId, bool favorite);
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models.Data;
namespace Bit.App.Abstractions
{
public interface ICollectionRepository : IRepository<CollectionData, string>
{
Task<IEnumerable<CollectionData>> GetAllByUserIdAsync(string userId);
}
}

View File

@@ -1,10 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface IConnectApiRepository
{
Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj);
}
}

View File

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models.Api;
using Bit.App.Repositories;
namespace Bit.App.Abstractions
{
public interface IDeviceApiRepository : IApiRepository<DeviceRequest, DeviceResponse, string>
{
Task<ApiResult> PutTokenAsync(string identifier, DeviceTokenRequest request);
Task<ApiResult> PutClearTokenAsync(string identifier);
}
}

View File

@@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface IFolderApiRepository : IApiRepository<FolderRequest, FolderResponse, string>
{ }
}

View File

@@ -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 IFolderRepository : IRepository<FolderData, string>
{
Task<IEnumerable<FolderData>> GetAllByUserIdAsync(string userId);
Task DeleteWithCipherUpdateAsync(string id, DateTime revisionDate);
}
}

View File

@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Bit.App.Abstractions
{
public interface IRepository<T, TId>
where T : class, IDataObject<TId>, new()
where TId : IEquatable<TId>
{
Task<T> GetByIdAsync(TId id);
Task<IEnumerable<T>> GetAllAsync();
Task UpdateAsync(T obj);
Task InsertAsync(T obj);
Task UpsertAsync(T obj);
Task DeleteAsync(TId id);
Task DeleteAsync(T obj);
}
}

View File

@@ -1,10 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface ISettingsApiRepository
{
Task<ApiResult<DomainsResponse>> GetDomains(bool excluded = false);
}
}

View File

@@ -1,8 +0,0 @@
using Bit.App.Models.Data;
namespace Bit.App.Abstractions
{
public interface ISettingsRepository : IRepository<SettingsData, string>
{
}
}

View File

@@ -1,10 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface ISyncApiRepository
{
Task<ApiResult<SyncResponse>> Get();
}
}

View File

@@ -1,10 +0,0 @@
using System.Threading.Tasks;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface ITwoFactorApiRepository
{
Task<ApiResult> PostSendEmailLoginAsync(TwoFactorEmailRequest requestObj);
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IAppIdService
{
string AppId { get; }
string AnonymousAppId { get; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IAppInfoService
{
string Build { get; }
string Version { get; }
bool AutofillAccessibilityServiceEnabled { get; }
bool AutofillServiceEnabled { get; }
}
}

View File

@@ -1,24 +0,0 @@
using System;
namespace Bit.App.Abstractions
{
public interface IAppSettingsService
{
bool Locked { get; set; }
int FailedPinAttempts { get; set; }
DateTime LastActivity { get; set; }
DateTime LastCacheClear { get; set; }
bool AutofillPersistNotification { get; set; }
bool AutofillPasswordField { get; set; }
bool DisableWebsiteIcons { get; set; }
string SecurityStamp { get; set; }
string BaseUrl { get; set; }
string WebVaultUrl { get; set; }
string ApiUrl { get; set; }
string IdentityUrl { get; set; }
string IconsUrl { get; set; }
bool ClearCiphersCache { get; set; }
bool ClearExtensionCiphersCache { get; set; }
bool OrganizationGivesPremium { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models;
using System.Threading.Tasks;
namespace Bit.App.Abstractions
{
public interface IAuthService
{
bool IsAuthenticated { get; }
string UserId { get; set; }
string PreviousUserId { get; }
bool UserIdChanged { get; }
string Email { get; set; }
KdfType Kdf { get; set; }
int KdfIterations { get; set; }
string PIN { get; set; }
bool BelongsToOrganization(string orgId);
void LogOut(string logoutMessage = null);
Task<FullLoginResult> TokenPostAsync(string email, string masterPassword);
Task<LoginResult> TokenPostTwoFactorAsync(TwoFactorProviderType type, string token, bool remember, string email,
string masterPasswordHash, SymmetricCryptoKey key);
}
}

View File

@@ -1,28 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Models.Api;
using System;
using Bit.App.Models.Data;
namespace Bit.App.Abstractions
{
public interface ICipherService
{
Task<Cipher> GetByIdAsync(string id);
Task<IEnumerable<Cipher>> GetAllAsync();
Task<IEnumerable<Cipher>> GetAllAsync(bool favorites);
Task<IEnumerable<Cipher>> GetAllByFolderAsync(string folderId);
Task<IEnumerable<Cipher>> GetAllByCollectionAsync(string collectionId);
Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString);
Task<ApiResult<CipherResponse>> SaveAsync(Cipher cipher);
Task UpsertDataAsync(CipherData cipher, bool sendMessage, bool created);
Task<ApiResult> DeleteAsync(string id);
Task DeleteDataAsync(string id, bool sendMessage);
Task<byte[]> DownloadAndDecryptAttachmentAsync(string url, CipherString key, string orgId = null);
Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Cipher cipher, byte[] data, string fileName);
Task UpsertAttachmentDataAsync(IEnumerable<AttachmentData> attachments);
Task<ApiResult> DeleteAttachmentAsync(Cipher cipher, string attachmentId);
Task DeleteAttachmentDataAsync(string attachmentId);
}
}

View File

@@ -1,14 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models;
using System;
namespace Bit.App.Abstractions
{
public interface ICollectionService
{
Task<Collection> GetByIdAsync(string id);
Task<IEnumerable<Collection>> GetAllAsync();
Task<IEnumerable<Tuple<string, string>>> GetAllCipherAssociationsAsync();
}
}

View File

@@ -1,32 +0,0 @@
using Bit.App.Enums;
using Bit.App.Models;
using Bit.App.Models.Api;
using System;
using System.Collections.Generic;
namespace Bit.App.Abstractions
{
public interface ICryptoService
{
SymmetricCryptoKey Key { get; set; }
SymmetricCryptoKey EncKey { get; }
byte[] PrivateKey { get; }
IDictionary<string, SymmetricCryptoKey> OrgKeys { get; }
void SetEncKey(CipherString encKeyEnc);
void SetPrivateKey(CipherString privateKeyEnc);
void SetOrgKeys(ProfileResponse profile);
void SetOrgKeys(Dictionary<string, string> orgKeysEncDict);
SymmetricCryptoKey GetOrgKey(string orgId);
void ClearKeys();
string Decrypt(CipherString encyptedValue, SymmetricCryptoKey key = null);
byte[] DecryptToBytes(CipherString encyptedValue, SymmetricCryptoKey key = null);
byte[] DecryptToBytes(byte[] encyptedValue, SymmetricCryptoKey key = null);
byte[] RsaDecryptToBytes(CipherString encyptedValue, byte[] privateKey);
CipherString Encrypt(string plaintextValue, SymmetricCryptoKey key = null);
byte[] EncryptToBytes(byte[] plainBytes, SymmetricCryptoKey key = null);
SymmetricCryptoKey MakeKeyFromPassword(string password, string salt, KdfType kdf, int kdfIterations);
byte[] HashPassword(SymmetricCryptoKey key, string password);
string HashPasswordBase64(SymmetricCryptoKey key, string password);
Tuple<SymmetricCryptoKey, CipherString> MakeEncKey(SymmetricCryptoKey key);
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IDatabaseService
{
void CreateTables();
}
}

View File

@@ -1,28 +0,0 @@
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Abstractions
{
public interface IDeviceActionService
{
Task ShowLoadingAsync(string text);
Task HideLoadingAsync();
void Toast(string text, bool longDuration = false);
void CopyToClipboard(string text);
bool OpenFile(byte[] fileData, string id, string fileName);
bool CanOpenFile(string fileName);
Task SelectFileAsync();
void ClearCache();
void Autofill(Models.Page.VaultListPageModel.Cipher cipher);
void CloseAutofill();
void Background();
void RateApp();
void DismissKeyboard();
void OpenAccessibilitySettings();
void OpenAutofillSettings();
Task LaunchAppAsync(string appName, Page page);
Task<string> DisplayPromptAync(string title = null, string description = null, string text = null);
Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons);
}
}

View File

@@ -1,15 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IDeviceInfoService
{
string Type { get; }
string Model { get; }
int Version { get; }
float Scale { get; }
bool NfcEnabled { get; }
bool HasCamera { get; }
bool AutofillServiceSupported { get; }
bool HasFaceIdSupport { get; }
bool IsExtension { get; }
}
}

View File

@@ -1,15 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Models.Api;
namespace Bit.App.Abstractions
{
public interface IFolderService
{
Task<Folder> GetByIdAsync(string id);
Task<IEnumerable<Folder>> GetAllAsync();
Task<ApiResult<FolderResponse>> SaveAsync(Folder folder);
Task<ApiResult> DeleteAsync(string folderId);
}
}

View File

@@ -1,16 +0,0 @@
using System;
namespace Bit.App.Abstractions
{
public interface IGoogleAnalyticsService
{
void TrackPage(string pageName);
void TrackAppEvent(string eventName, string label = null);
void TrackExtensionEvent(string eventName, string label = null);
void TrackAutofillExtensionEvent(string eventName, string label = null);
void TrackEvent(string category, string eventName, string label = null);
void TrackException(string message, bool fatal);
void Dispatch(Action completionHandler = null);
void SetAppOptOut(bool optOut);
}
}

View File

@@ -1,8 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IHttpService
{
ApiHttpClient ApiClient { get; }
IdentityHttpClient IdentityClient { get; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IKeyDerivationService
{
byte[] DeriveKey(byte[] password, byte[] salt, uint rounds);
}
}

View File

@@ -1,31 +0,0 @@
using System;
using System.Globalization;
namespace Bit.App.Abstractions
{
/// <summary>
/// Implementations of this interface MUST convert iOS and Android
/// platform-specific locales to a value supported in .NET because
/// ONLY valid .NET cultures can have their RESX resources loaded and used.
/// </summary>
/// <remarks>
/// Lists of valid .NET cultures can be found here:
/// http://www.localeplanet.com/dotnet/
/// http://www.csharp-examples.net/culture-names/
/// You should always test all the locales implemented in your application.
/// </remarks>
public interface ILocalizeService
{
/// <summary>
/// This method must evaluate platform-specific locale settings
/// and convert them (when necessary) to a valid .NET locale.
/// </summary>
CultureInfo GetCurrentCultureInfo();
/// <summary>
/// CurrentCulture and CurrentUICulture must be set in the platform project,
/// because the Thread object can't be accessed in a PCL.
/// </summary>
void SetLocale(CultureInfo ci);
}
}

View File

@@ -1,14 +0,0 @@
using Bit.App.Enums;
using System;
using System.Threading.Tasks;
namespace Bit.App.Abstractions
{
public interface ILockService
{
void UpdateLastActivity();
Task<LockType> GetLockTypeAsync(bool forceLock, bool onlyIfAlreadyLocked = false);
Task CheckLockAsync(bool forceLock, bool onlyIfAlreadyLocked = false);
bool TopPageIsLock();
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Abstractions
{
public interface ILogService
{
void WriteLine(string message);
}
}

View File

@@ -1,17 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IPasswordGenerationService
{
string GeneratePassword(
int? length = null,
bool? uppercase = null,
bool? lowercase = null,
bool? numbers = null,
bool? special = null,
bool? ambiguous = null,
int? minUppercase = null,
int? minLowercase = null,
int? minNumbers = null,
int? minSpecial = null);
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IPushNotificationService
{
string Token { get; }
void Register();
void Unregister();
}
}

View File

@@ -1,13 +0,0 @@
using Newtonsoft.Json.Linq;
namespace Bit.App.Abstractions
{
public interface IPushNotificationListener
{
void OnMessage(JObject values, string device);
void OnRegistered(string token, string device);
void OnUnregistered(string device);
void OnError(string message, string device);
bool ShouldShowNotification();
}
}

View File

@@ -1,10 +0,0 @@
namespace Bit.App.Abstractions
{
public interface ISecureStorageService
{
void Store(string key, byte[] dataBytes);
byte[] Retrieve(string key);
void Delete(string key);
bool Contains(string key);
}
}

View File

@@ -1,10 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Bit.App.Abstractions
{
public interface ISettingsService
{
Task<IEnumerable<IEnumerable<string>>> GetEquivalentDomainsAsync();
}
}

View File

@@ -1,9 +0,0 @@
using SQLite;
namespace Bit.App.Abstractions
{
public interface ISqlService
{
SQLiteConnection GetConnection();
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Threading.Tasks;
namespace Bit.App.Abstractions
{
public interface ISyncService
{
bool SyncInProgress { get; }
Task<bool> SyncCipherAsync(string id);
Task<bool> SyncFolderAsync(string id);
Task<bool> SyncDeleteFolderAsync(string id, DateTime revisionDate);
Task<bool> SyncDeleteCipherAsync(string id);
Task<bool> SyncSettingsAsync();
Task<bool> SyncProfileAsync();
Task<bool> FullSyncAsync(bool forceSync = false);
Task<bool> FullSyncAsync(TimeSpan syncThreshold, bool forceSync = false);
}
}

View File

@@ -1,21 +0,0 @@
using System;
namespace Bit.App.Abstractions
{
public interface ITokenService
{
string Token { get; set; }
string RefreshToken { get; set; }
string GetTwoFactorToken(string email);
void SetTwoFactorToken(string email, string token);
DateTime TokenExpiration { get; }
string TokenIssuer { get; }
bool TokenExpired { get; }
TimeSpan TokenTimeRemaining { get; }
bool TokenNeedsRefresh { get; }
string TokenUserId { get; }
string TokenEmail { get; }
string TokenName { get; }
bool TokenPremium { get; }
}
}

View File

@@ -1,327 +0,0 @@
using System;
using System.Linq;
using Bit.App.Abstractions;
using Bit.App.Pages;
using Xamarin.Forms;
using System.Diagnostics;
using System.Threading.Tasks;
using Plugin.Settings.Abstractions;
using Bit.App.Controls;
using Plugin.Connectivity.Abstractions;
using System.Net;
using System.Reflection;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.App.Models;
namespace Bit.App
{
public class App : Application
{
private AppOptions _options;
private readonly IAuthService _authService;
private readonly IDatabaseService _databaseService;
private readonly IConnectivity _connectivity;
private readonly ISyncService _syncService;
private readonly ISettings _settings;
private readonly ILockService _lockService;
private readonly ILocalizeService _localizeService;
private readonly IAppInfoService _appInfoService;
private readonly IAppSettingsService _appSettingsService;
private readonly IDeviceActionService _deviceActionService;
public App(
AppOptions options,
IAuthService authService,
IConnectivity connectivity,
IDatabaseService databaseService,
ISyncService syncService,
ISettings settings,
ILockService lockService,
ILocalizeService localizeService,
IAppInfoService appInfoService,
IAppSettingsService appSettingsService,
IDeviceActionService deviceActionService)
{
_options = options ?? new AppOptions();
_authService = authService;
_databaseService = databaseService;
_connectivity = connectivity;
_syncService = syncService;
_settings = settings;
_lockService = lockService;
_localizeService = localizeService;
_appInfoService = appInfoService;
_appSettingsService = appSettingsService;
_deviceActionService = deviceActionService;
SetCulture();
SetStyles();
if(authService.IsAuthenticated)
{
if(_options.FromAutofillFramework && _options.SaveType.HasValue)
{
MainPage = new ExtendedNavigationPage(new VaultAddCipherPage(_options));
}
else if(_options.Uri != null)
{
MainPage = new ExtendedNavigationPage(new VaultAutofillListCiphersPage(_options));
}
else
{
MainPage = new MainPage();
}
}
else
{
MainPage = new ExtendedNavigationPage(new HomePage());
}
MessagingCenter.Subscribe<Application, bool>(Current, "Resumed", async (sender, forceLock) =>
{
Device.BeginInvokeOnMainThread(async () => await _lockService.CheckLockAsync(forceLock));
if(Device.RuntimePlatform == Device.iOS)
{
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
}
});
}
protected async override void OnStart()
{
// Handle when your app starts
await _lockService.CheckLockAsync(false);
if(string.IsNullOrWhiteSpace(_options.Uri))
{
var updated = Helpers.PerformUpdateTasks(_settings, _appInfoService, _databaseService, _syncService);
if(!updated)
{
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
}
}
if((DateTime.UtcNow - _appSettingsService.LastCacheClear).TotalDays >= 1)
{
await Task.Run(() => _deviceActionService.ClearCache()).ConfigureAwait(false);
}
Debug.WriteLine("OnStart");
}
protected override void OnSleep()
{
// Handle when your app sleeps
Debug.WriteLine("OnSleep");
SetMainPageFromAutofill();
if(Device.RuntimePlatform == Device.Android && !_lockService.TopPageIsLock())
{
_lockService.UpdateLastActivity();
}
}
protected async override void OnResume()
{
base.OnResume();
// workaround for app compat bug
// ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity
await Task.Delay(10);
// Handle when your app resumes
Debug.WriteLine("OnResume");
if(Device.RuntimePlatform == Device.Android)
{
await _lockService.CheckLockAsync(false);
}
var lockPinPage = Current.MainPage.Navigation.ModalStack.LastOrDefault() as LockPinPage;
if(lockPinPage != null)
{
lockPinPage.PinControl.Entry.FocusWithDelay();
}
if(Device.RuntimePlatform == Device.Android)
{
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
}
var now = DateTime.UtcNow;
if((now - _appSettingsService.LastCacheClear).TotalDays >= 1
&& (now - _appSettingsService.LastActivity).TotalHours >= 1)
{
await Task.Run(() => _deviceActionService.ClearCache()).ConfigureAwait(false);
}
}
private void SetMainPageFromAutofill()
{
if(Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(_options.Uri) &&
!_options.FromAutofillFramework)
{
Task.Run(() =>
{
Device.BeginInvokeOnMainThread(() =>
{
Current.MainPage = new MainPage();
_options.Uri = null;
});
});
}
}
private async Task FullSyncAsync()
{
if(_connectivity.IsConnected)
{
var attempt = 0;
do
{
try
{
await _syncService.FullSyncAsync(TimeSpan.FromMinutes(30)).ConfigureAwait(false);
break;
}
catch(WebException)
{
Debug.WriteLine("Failed to full sync.");
if(attempt >= 1)
{
break;
}
else
{
await Task.Delay(1000);
}
attempt++;
}
catch(Exception e) when(e is TaskCanceledException || e is OperationCanceledException)
{
Debug.WriteLine("Cancellation exception.");
break;
}
} while(attempt <= 1);
}
else
{
Debug.WriteLine("Not connected.");
}
}
private void SetStyles()
{
var gray = Color.FromHex("333333");
var grayLight = Color.FromHex("777777");
var grayLighter = Color.FromHex("d2d6de");
var primaryColor = Color.FromHex("3c8dbc");
var primaryColorAccent = Color.FromHex("286090");
Resources = new ResourceDictionary();
// Labels
Resources.Add("text-muted", new Style(typeof(Label))
{
Setters = {
new Setter { Property = Label.TextColorProperty, Value = grayLight }
}
});
// Buttons
Resources.Add("btn-default", new Style(typeof(Button))
{
Setters = {
new Setter { Property = Button.TextColorProperty, Value = gray }
}
});
Resources.Add("btn-primary", new Style(typeof(Button))
{
Setters = {
new Setter { Property = Button.TextColorProperty, Value = Color.White },
new Setter { Property = Button.BackgroundColorProperty, Value = primaryColor },
new Setter { Property = Button.FontAttributesProperty, Value = FontAttributes.Bold },
new Setter { Property = Button.BorderRadiusProperty, Value = 0 }
}
});
Resources.Add("btn-primaryAccent", new Style(typeof(Button))
{
Setters = {
new Setter { Property = Button.TextColorProperty, Value = primaryColorAccent }
}
});
Resources.Add("btn-white", new Style(typeof(Button))
{
Setters = {
new Setter { Property = Button.BackgroundColorProperty, Value = Color.White },
new Setter { Property = Button.TextColorProperty, Value = primaryColor },
new Setter { Property = Button.FontAttributesProperty, Value = FontAttributes.Bold },
new Setter { Property = Button.BorderRadiusProperty, Value = 0 }
}
});
Resources.Add(new Style(typeof(Button))
{
Setters = {
new Setter { Property = Button.TextColorProperty, Value = primaryColor }
}
});
Resources.Add(new Style(typeof(ExtendedButton))
{
Setters = {
new Setter { Property = Button.TextColorProperty, Value = primaryColor }
}
});
// List View
Resources.Add(new Style(typeof(ExtendedListView))
{
Setters = {
new Setter { Property = ListView.SeparatorColorProperty, Value = grayLighter }
}
});
// Search Bar
Resources.Add(new Style(typeof(SearchBar))
{
Setters = {
new Setter { Property = SearchBar.CancelButtonColorProperty, Value = primaryColor }
}
});
}
private void SetCulture()
{
Debug.WriteLine("====== resource debug info =========");
var assembly = typeof(App).GetTypeInfo().Assembly;
foreach(var res in assembly.GetManifestResourceNames())
{
Debug.WriteLine("found resource: " + res);
}
Debug.WriteLine("====================================");
// This lookup NOT required for Windows platforms - the Culture will be automatically set
if(Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.Android)
{
var ci = _localizeService.GetCurrentCultureInfo();
AppResources.Culture = ci;
_localizeService.SetLocale(ci);
}
// Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077
new System.Globalization.ThaiBuddhistCalendar();
new System.Globalization.HijriCalendar();
new System.Globalization.UmAlQuraCalendar();
}
}
}

View File

@@ -1,292 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net471</TargetFrameworks>
<RootNamespace>Bit.App</RootNamespace>
<AssemblyName>BitwardenApp</AssemblyName>
<NeutralLanguage>en-US</NeutralLanguage>
<Configurations>Debug;Release;FDroid</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)' == 'FDroid|netstandard2.0|AnyCPU'">
<DefineConstants>TRACE;FDROID;NETSTANDARD2_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)' == 'FDroid|net471|AnyCPU'">
<DefineConstants>TRACE;FDROID;NET471</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\public_suffix_list.dat" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\public_suffix_list.dat" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HockeySDK.Xamarin" Version="5.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="Plugin.Fingerprint" Version="1.4.9" />
<PackageReference Include="Refractored.FloatingActionButtonForms" Version="2.1.0" />
<PackageReference Include="sqlite-net-pcl" Version="1.5.231" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.2.0" />
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.4.859" />
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
<PackageReference Include="XLabs.IoC" Version="2.0.5782" />
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.1.47" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\AppResources.cs.Designer.cs">
<DependentUpon>AppResources.cs.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.da.Designer.cs">
<DependentUpon>AppResources.da.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.de.Designer.cs">
<DependentUpon>AppResources.de.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>AppResources.resx</DependentUpon>
</Compile>
<Compile Update="Resources\AppResources.es.Designer.cs">
<DependentUpon>AppResources.es.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.fi.Designer.cs">
<DependentUpon>AppResources.fi.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.fr.Designer.cs">
<DependentUpon>AppResources.fr.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.hi.Designer.cs">
<DependentUpon>AppResources.hi.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.hr.Designer.cs">
<DependentUpon>AppResources.hr.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.hu.Designer.cs">
<DependentUpon>AppResources.hu.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.id.Designer.cs">
<DependentUpon>AppResources.id.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.it.Designer.cs">
<DependentUpon>AppResources.it.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.ja.Designer.cs">
<DependentUpon>AppResources.ja.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.nl.Designer.cs">
<DependentUpon>AppResources.nl.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.pl.Designer.cs">
<DependentUpon>AppResources.pl.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.pt-BR.Designer.cs">
<DependentUpon>AppResources.pt-BR.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.pt-PT.Designer.cs">
<DependentUpon>AppResources.pt-PT.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.ro.Designer.cs">
<DependentUpon>AppResources.ro.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.ru.Designer.cs">
<DependentUpon>AppResources.ru.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.sk.Designer.cs">
<DependentUpon>AppResources.sk.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.sv.Designer.cs">
<DependentUpon>AppResources.sv.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.th.Designer.cs">
<DependentUpon>AppResources.th.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.tr.Designer.cs">
<DependentUpon>AppResources.tr.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.uk.Designer.cs">
<DependentUpon>AppResources.uk.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.vi.Designer.cs">
<DependentUpon>AppResources.vi.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.zh-Hans.Designer.cs">
<DependentUpon>AppResources.zh-Hans.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Resources\AppResources.zh-Hant.Designer.cs">
<DependentUpon>AppResources.zh-Hant.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\AppResources.cs.resx">
<LastGenOutput>AppResources.cs.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.da.resx">
<LastGenOutput>AppResources.da.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.de.resx">
<LastGenOutput>AppResources.de.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.es.resx">
<LastGenOutput>AppResources.es.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.fi.resx">
<LastGenOutput>AppResources.fi.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.fr.resx">
<LastGenOutput>AppResources.fr.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.hi.resx">
<LastGenOutput>AppResources.hi.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.hr.resx">
<LastGenOutput>AppResources.hr.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.hu.resx">
<LastGenOutput>AppResources.hu.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.id.resx">
<LastGenOutput>AppResources.id.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.it.resx">
<LastGenOutput>AppResources.it.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.ja.resx">
<LastGenOutput>AppResources.ja.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.nl.resx">
<LastGenOutput>AppResources.nl.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.pl.resx">
<LastGenOutput>AppResources.pl.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.pt-BR.resx">
<LastGenOutput>AppResources.pt-BR.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.pt-PT.resx">
<LastGenOutput>AppResources.pt-PT.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>AppResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.ro.resx">
<LastGenOutput>AppResources.ro.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.ru.resx">
<LastGenOutput>AppResources.ru.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.sk.resx">
<LastGenOutput>AppResources.sk.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.sv.resx">
<LastGenOutput>AppResources.sv.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.th.resx">
<LastGenOutput>AppResources.th.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.tr.resx">
<LastGenOutput>AppResources.tr.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.uk.resx">
<LastGenOutput>AppResources.uk.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.vi.resx">
<LastGenOutput>AppResources.vi.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.zh-Hans.resx">
<LastGenOutput>AppResources.zh-Hans.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\AppResources.zh-Hant.resx">
<LastGenOutput>AppResources.zh-Hant.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -1,56 +0,0 @@
namespace Bit.App
{
public static class Constants
{
public const string AndroidAppProtocol = "androidapp://";
public const string iOSAppProtocol = "iosapp://";
public const string SettingFingerprintUnlockOn = "setting:fingerprintUnlockOn";
public const string SettingPinUnlockOn = "setting:pinUnlockOn";
public const string SettingLockSeconds = "setting:lockSeconds";
public const string SettingGaOptOut = "setting:googleAnalyticsOptOut";
public const string SettingDisableWebsiteIcons = "setting:disableWebsiteIcons";
public const string SettingDisableTotpCopy = "setting:disableAutoCopyTotp";
public const string AutofillPersistNotification = "setting:persistNotification";
public const string AutofillPasswordField = "setting:autofillPasswordField";
public const string PasswordGeneratorLength = "pwGenerator:length";
public const string PasswordGeneratorUppercase = "pwGenerator:uppercase";
public const string PasswordGeneratorLowercase = "pwGenerator:lowercase";
public const string PasswordGeneratorNumbers = "pwGenerator:numbers";
public const string PasswordGeneratorMinNumbers = "pwGenerator:minNumbers";
public const string PasswordGeneratorSpecial = "pwGenerator:special";
public const string PasswordGeneratorMinSpecial = "pwGenerator:minSpecial";
public const string PasswordGeneratorAmbiguous = "pwGenerator:ambiguous";
public const string PushInitialPromptShown = "push:initialPromptShown";
public const string PushLastRegistrationDate = "push:lastRegistrationDate";
public const string PushCurrentToken = "push:currentToken";
public const string PushRegisteredToken = "push:registeredToken";
public const string ExtensionStarted = "extension:started";
public const string ExtensionActivated = "extension:activated";
public const string SecurityStamp = "other:securityStamp";
public const string LastActivityDate = "other:lastActivityDate";
public const string LastActivityLockTime = "other:lastActivityLockTime";
public const string LastCacheClearDate = "other:cacheClearDate";
public const string Locked = "other:locked";
public const string LockTimerId = "other:lockTimerId";
public const string LastLoginEmail = "other:lastLoginEmail";
public const string LastSync = "other:lastSync";
public const string LastBuildKey = "LastBuild";
public const string BaseUrl = "other:baseUrl";
public const string WebVaultUrl = "other:webVaultUrl";
public const string ApiUrl = "other:apiUrl";
public const string IdentityUrl = "other:identityUrl";
public const string IconsUrl = "other:iconsUrl";
public const string FailedPinAttempts = "other:failedPinAttempts";
public const string ClearCiphersCache = "other:clearCiphersCache";
public const string ClearExtensionCiphersCache = "other:clearExtensionCiphersCache";
public const string OrgGivesPremium = "other:orgGivesPremium";
public const int SelectFileRequestCode = 42;
public const int SelectFilePermissionRequestCode = 43;
}
}

View File

@@ -1,16 +0,0 @@
using Bit.App.Resources;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class AddCipherToolBarItem : ExtendedToolbarItem
{
public AddCipherToolBarItem(Page page, string folderId)
: base(() => Helpers.AddCipher(page, folderId))
{
Text = AppResources.Add;
Icon = "plus.png";
}
}
}

View File

@@ -1,29 +0,0 @@
using Bit.App.Resources;
using Bit.App.Utilities;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class DismissModalToolBarItem : ExtendedToolbarItem, IDisposable
{
private readonly ContentPage _page;
public DismissModalToolBarItem(ContentPage page, string text = null, Action cancelClickedAction = null)
: base(cancelClickedAction)
{
_page = page;
// TODO: init and dispose events from pages
InitEvents();
Text = text ?? AppResources.Close;
Icon = Helpers.ToolbarImage("ion_chevron_left.png");
Priority = -1;
}
protected async override void ClickedItem(object sender, EventArgs e)
{
base.ClickedItem(sender, e);
await _page.Navigation.PopForDeviceAsync();
}
}
}

View File

@@ -1,28 +0,0 @@
using Bit.App.Enums;
using Bit.App.Utilities;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedButton : Button
{
public static readonly BindableProperty PaddingProperty =
BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(ExtendedButton), default(Thickness));
public static readonly BindableProperty UppercaseProperty =
BindableProperty.Create(nameof(Uppercase), typeof(bool), typeof(ExtendedButton),
Helpers.OnPlatform(iOS: false, Android: true, Windows: false));
public Thickness Padding
{
get { return (Thickness)GetValue(PaddingProperty); }
set { SetValue(PaddingProperty, value); }
}
public bool Uppercase
{
get { return (bool)GetValue(UppercaseProperty); }
set { SetValue(UppercaseProperty, value); }
}
}
}

View File

@@ -1,81 +0,0 @@
using Bit.App.Abstractions;
using Bit.App.Pages;
using Xamarin.Forms;
using XLabs.Ioc;
namespace Bit.App.Controls
{
public class ExtendedContentPage : ContentPage
{
private ISyncService _syncService;
private IGoogleAnalyticsService _googleAnalyticsService;
private ILockService _lockService;
private IDeviceActionService _deviceActionService;
private IAuthService _authService;
private bool _syncIndicator;
private bool _updateActivity;
private bool _requireAuth;
public ExtendedContentPage(bool syncIndicator = false, bool updateActivity = true, bool requireAuth = true)
{
_syncIndicator = syncIndicator;
_updateActivity = updateActivity;
_requireAuth = requireAuth;
_syncService = Resolver.Resolve<ISyncService>();
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
_lockService = Resolver.Resolve<ILockService>();
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
_authService = Resolver.Resolve<IAuthService>();
BackgroundColor = Color.FromHex("efeff4");
}
protected async override void OnAppearing()
{
if(_requireAuth && !_authService.IsAuthenticated)
{
Device.BeginInvokeOnMainThread(
() => Application.Current.MainPage = new ExtendedNavigationPage(new HomePage()));
}
if(_syncIndicator)
{
MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted",
(sender, success) => Device.BeginInvokeOnMainThread(() => IsBusy = _syncService.SyncInProgress));
MessagingCenter.Subscribe<ISyncService>(Application.Current, "SyncStarted",
(sender) => Device.BeginInvokeOnMainThread(() => IsBusy = _syncService.SyncInProgress));
}
if(_syncIndicator)
{
IsBusy = _syncService.SyncInProgress;
}
_googleAnalyticsService.TrackPage(GetType().Name);
await _lockService.CheckLockAsync(false, true);
base.OnAppearing();
}
protected override void OnDisappearing()
{
if(_syncIndicator)
{
MessagingCenter.Unsubscribe<Application, bool>(Application.Current, "SyncCompleted");
MessagingCenter.Unsubscribe<Application>(Application.Current, "SyncStarted");
}
if(_syncIndicator)
{
IsBusy = false;
}
if(_updateActivity)
{
_lockService.UpdateLastActivity();
}
base.OnDisappearing();
_deviceActionService.DismissKeyboard();
}
}
}

View File

@@ -1,17 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedEditor : Editor
{
public static readonly BindableProperty HasBorderProperty =
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEditor), true);
public bool HasBorder
{
get { return (bool)GetValue(HasBorderProperty); }
set { SetValue(HasBorderProperty, value); }
}
}
}

View File

@@ -1,86 +0,0 @@
using Bit.App.Enums;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedEntry : Entry
{
public ExtendedEntry()
{
if(Device.RuntimePlatform == Device.Android)
{
PlaceholderColor = Color.FromHex("c7c7cd");
}
IsPasswordFromToggled = IsPassword;
}
public static readonly BindableProperty HasBorderProperty =
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEntry), true);
public static readonly BindableProperty HasOnlyBottomBorderProperty =
BindableProperty.Create(nameof(HasOnlyBottomBorder), typeof(bool), typeof(ExtendedEntry), false);
public static readonly BindableProperty BottomBorderColorProperty =
BindableProperty.Create(nameof(BottomBorderColor), typeof(Color), typeof(ExtendedEntry), Color.Default);
public static readonly BindableProperty TargetMaxLengthProperty =
BindableProperty.Create(nameof(TargetMaxLength), typeof(int), typeof(ExtendedEntry), int.MaxValue);
public bool HasBorder
{
get { return (bool)GetValue(HasBorderProperty); }
set { SetValue(HasBorderProperty, value); }
}
public bool HasOnlyBottomBorder
{
get { return (bool)GetValue(HasOnlyBottomBorderProperty); }
set { SetValue(HasOnlyBottomBorderProperty, value); }
}
public Color BottomBorderColor
{
get { return (Color)GetValue(BottomBorderColorProperty); }
set { SetValue(BottomBorderColorProperty, value); }
}
public int TargetMaxLength
{
get { return (int)GetValue(TargetMaxLengthProperty); }
set { SetValue(TargetMaxLengthProperty, value); }
}
public Enums.ReturnType? TargetReturnType { get; set; }
public bool? Autocorrect { get; set; }
public bool DisableAutocapitalize { get; set; }
public bool AllowClear { get; set; }
public bool HideCursor { get; set; }
public bool NumbersOnly { get; set; }
// Need to overwrite default handler because we cant Invoke otherwise
public new event EventHandler Completed;
public void InvokeCompleted()
{
Completed?.Invoke(this, null);
}
public virtual void InvokeToggleIsPassword()
{
if(ToggleIsPassword == null)
{
IsPassword = IsPasswordFromToggled = !IsPassword;
Focus();
}
else
{
ToggleIsPassword.Invoke(this, null);
}
}
public event EventHandler ToggleIsPassword;
public bool IsPasswordFromToggled { get; set; } = false;
}
}

View File

@@ -1,16 +0,0 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedListView : ListView
{
public static readonly BindableProperty BottomPaddingProperty =
BindableProperty.Create(nameof(BottomPadding), typeof(int), typeof(ExtendedTableView), 0);
public ExtendedListView() { }
public ExtendedListView(ListViewCachingStrategy cachingStrategy)
: base(cachingStrategy) { }
public int BottomPadding { get; set; }
}
}

View File

@@ -1,27 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedNavigationPage : NavigationPage
{
public ExtendedNavigationPage()
: base()
{
SetDefaults();
}
public ExtendedNavigationPage(Page root)
: base(root)
{
SetDefaults();
}
private void SetDefaults()
{
// default colors for our app
BarBackgroundColor = Color.FromHex("3c8dbc");
BarTextColor = Color.White;
}
}
}

View File

@@ -1,19 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedPicker : Picker
{
// TODO: text color
public static readonly BindableProperty HasBorderProperty =
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEntry), true);
public bool HasBorder
{
get { return (bool)GetValue(HasBorderProperty); }
set { SetValue(HasBorderProperty, value); }
}
}
}

View File

@@ -1,16 +0,0 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedSwitchCell : SwitchCell
{
public static readonly BindableProperty BackgroundColorProperty =
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedSwitchCell), Color.White);
public Color BackgroundColor
{
get { return (Color)GetValue(BackgroundColorProperty); }
set { SetValue(BackgroundColorProperty, value); }
}
}
}

View File

@@ -1,24 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedTabbedPage : TabbedPage
{
public ExtendedTabbedPage()
{
BackgroundColor = Color.FromHex("efeff4");
}
public static readonly BindableProperty TintColorProperty =
BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(ExtendedTabbedPage), Color.White);
public Color TintColor
{
get { return (Color)GetValue(TintColorProperty); }
set { SetValue(TintColorProperty, value); }
}
public bool NoBorder { get; set; }
}
}

View File

@@ -1,80 +0,0 @@
using Xamarin.Forms;
using System;
using System.Reflection;
namespace Bit.App.Controls
{
public class ExtendedTableView : TableView
{
public static readonly BindableProperty EnableScrollingProperty =
BindableProperty.Create(nameof(EnableScrolling), typeof(bool), typeof(ExtendedTableView), true);
public static readonly BindableProperty EnableSelectionProperty =
BindableProperty.Create(nameof(EnableSelection), typeof(bool), typeof(ExtendedTableView), true);
public static readonly BindableProperty SeparatorColorProperty =
BindableProperty.Create(nameof(SeparatorColor), typeof(Color), typeof(ExtendedTableView), Color.FromHex("d2d6de"));
public static readonly BindableProperty BottomPaddingProperty =
BindableProperty.Create(nameof(BottomPadding), typeof(int), typeof(ExtendedTableView), 0);
public bool EnableScrolling
{
get { return (bool)GetValue(EnableScrollingProperty); }
set { SetValue(EnableScrollingProperty, value); }
}
public bool EnableSelection
{
get { return (bool)GetValue(EnableSelectionProperty); }
set { SetValue(EnableSelectionProperty, value); }
}
public Color SeparatorColor
{
get { return (Color)GetValue(SeparatorColorProperty); }
set { SetValue(SeparatorColorProperty, value); }
}
public int EstimatedRowHeight { get; set; }
public bool NoHeader { get; set; }
public bool NoFooter { get; set; }
public int BottomPadding { get; set; }
public Func<RedrawableStackLayout> WrappingStackLayout { get; set; }
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
{
if(!VerticalOptions.Expands && Device.RuntimePlatform != Device.UWP)
{
var baseOnSizeRequest = GetVisualElementOnSizeRequest();
return baseOnSizeRequest(widthConstraint, heightConstraint);
}
return base.OnSizeRequest(widthConstraint, heightConstraint);
}
private Func<double, double, SizeRequest> GetVisualElementOnSizeRequest()
{
var handle = typeof(VisualElement).GetMethod(
"OnSizeRequest",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { typeof(double), typeof(double) },
null)?.MethodHandle;
if(!handle.HasValue)
{
throw new ArgumentNullException("handle could not be found.");
}
var pointer = handle.Value.GetFunctionPointer();
if(pointer == null)
{
throw new ArgumentNullException("pointer could not be found.");
}
return (Func<double, double, SizeRequest>)Activator.CreateInstance(
typeof(Func<double, double, SizeRequest>), this, pointer);
}
}
}

View File

@@ -1,60 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedTextCell : TextCell
{
public ExtendedTextCell()
{
if(Device.RuntimePlatform == Device.Android)
{
TextColor = Color.Black;
}
DetailColor = Color.FromHex("777777");
}
public static readonly BindableProperty BackgroundColorProperty =
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedTextCell), Color.White);
public static readonly BindableProperty ShowDisclousureProperty =
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedTextCell), false);
public static readonly BindableProperty DisclousureImageProperty =
BindableProperty.Create(nameof(DisclousureImage), typeof(string), typeof(ExtendedTextCell), string.Empty);
public Color BackgroundColor
{
get { return (Color)GetValue(BackgroundColorProperty); }
set { SetValue(BackgroundColorProperty, value); }
}
public bool ShowDisclousure
{
get { return (bool)GetValue(ShowDisclousureProperty); }
set { SetValue(ShowDisclousureProperty, value); }
}
public string DisclousureImage
{
get { return (string)GetValue(DisclousureImageProperty); }
set { SetValue(DisclousureImageProperty, value); }
}
public LineBreakMode DetailLineBreakMode { get; set; } = LineBreakMode.TailTruncation;
public event EventHandler DisclousureTapped;
public void OnDisclousureTapped()
{
if(DisclousureTapped == null)
{
OnTapped();
return;
}
DisclousureTapped.Invoke(this, EventArgs.Empty);
}
}
}

View File

@@ -1,30 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedToolbarItem : ToolbarItem, IDisposable
{
public ExtendedToolbarItem(Action clickAction = null)
{
ClickAction = clickAction;
}
public Action ClickAction { get; set; }
protected virtual void ClickedItem(object sender, EventArgs e)
{
ClickAction?.Invoke();
}
public void InitEvents()
{
Clicked += ClickedItem;
}
public void Dispose()
{
Clicked -= ClickedItem;
}
}
}

View File

@@ -1,26 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class ExtendedViewCell : ViewCell
{
public static readonly BindableProperty BackgroundColorProperty =
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedViewCell), Color.White);
public static readonly BindableProperty ShowDisclousureProperty =
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedViewCell), false);
public Color BackgroundColor
{
get { return (Color)GetValue(BackgroundColorProperty); }
set { SetValue(BackgroundColorProperty, value); }
}
public bool ShowDisclousure
{
get { return (bool)GetValue(ShowDisclousureProperty); }
set { SetValue(ShowDisclousureProperty, value); }
}
}
}

View File

@@ -1,24 +0,0 @@
using Refractored.FabControl;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class Fab : FloatingActionButtonView
{
public Fab(FabLayout fabLayout, string icon, Action<object, EventArgs> clickedAction)
{
ImageName = icon;
ColorNormal = Color.FromHex("3c8dbc");
ColorPressed = Color.FromHex("3883af");
ColorRipple = Color.FromHex("3883af");
Clicked = clickedAction;
AbsoluteLayout.SetLayoutFlags(this, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(this, new Rectangle(1, 1, AbsoluteLayout.AutoSize,
AbsoluteLayout.AutoSize));
fabLayout.Children.Add(this);
}
}
}

View File

@@ -1,16 +0,0 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FabLayout : AbsoluteLayout
{
public FabLayout(View mainView)
{
VerticalOptions = LayoutOptions.FillAndExpand;
HorizontalOptions = LayoutOptions.FillAndExpand;
SetLayoutFlags(mainView, AbsoluteLayoutFlags.All);
SetLayoutBounds(mainView, new Rectangle(0, 0, 1, 1));
Children.Add(mainView);
}
}
}

View File

@@ -1,52 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FormEditorCell : ExtendedViewCell, IDisposable
{
public FormEditorCell(Keyboard entryKeyboard = null, double? height = null)
{
Editor = new ExtendedEditor
{
Keyboard = entryKeyboard,
HasBorder = false,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Editor))
};
if(height.HasValue)
{
Editor.HeightRequest = height.Value;
}
var stackLayout = new StackLayout
{
Padding = new Thickness(15, 10)
};
stackLayout.Children.Add(Editor);
Editor.AdjustMarginsForDevice();
stackLayout.AdjustPaddingForDevice();
View = stackLayout;
}
public ExtendedEditor Editor { get; private set; }
private void FormEditorCell_Tapped(object sender, EventArgs e)
{
Editor.Focus();
}
public void InitEvents()
{
Tapped += FormEditorCell_Tapped;
}
public void Dispose()
{
Tapped -= FormEditorCell_Tapped;
}
}
}

View File

@@ -1,225 +0,0 @@
using Bit.App.Abstractions;
using FFImageLoading.Forms;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using XLabs.Ioc;
namespace Bit.App.Controls
{
public class FormEntryCell : ExtendedViewCell, IDisposable
{
private VisualElement _nextElement;
private TapGestureRecognizer _tgr;
private StackLayout _buttonStackLayout = null;
public FormEntryCell(
string labelText,
Keyboard entryKeyboard = null,
bool isPassword = false,
VisualElement nextElement = null,
bool useLabelAsPlaceholder = false,
string imageSource = null,
Thickness? containerPadding = null,
string button1 = null,
string button2 = null)
{
if(!useLabelAsPlaceholder)
{
Label = new Label
{
Text = labelText,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.FillAndExpand
};
}
Entry = new ExtendedEntry
{
Keyboard = entryKeyboard,
HasBorder = false,
IsPassword = isPassword,
AllowClear = true,
HorizontalOptions = LayoutOptions.FillAndExpand,
WidthRequest = 1,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Entry))
};
if(useLabelAsPlaceholder)
{
Entry.Placeholder = labelText;
}
NextElement = nextElement;
var imageStackLayout = new StackLayout
{
Padding = containerPadding ?? new Thickness(15, 10),
Orientation = StackOrientation.Horizontal,
Spacing = 10,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
};
if(imageSource != null)
{
_tgr = new TapGestureRecognizer();
var theImage = new CachedImage
{
Source = imageSource,
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.Center,
WidthRequest = 18,
HeightRequest = 18
};
theImage.GestureRecognizers.Add(_tgr);
imageStackLayout.Children.Add(theImage);
}
var formStackLayout = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand
};
if(!useLabelAsPlaceholder)
{
formStackLayout.Children.Add(Label);
}
formStackLayout.Children.Add(Entry);
imageStackLayout.Children.Add(formStackLayout);
if(!string.IsNullOrWhiteSpace(button1) || !string.IsNullOrWhiteSpace(button2))
{
_buttonStackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 5
};
imageStackLayout.Children.Add(_buttonStackLayout);
if(!string.IsNullOrWhiteSpace(button1))
{
Button1 = new ExtendedButton { Image = button1 };
_buttonStackLayout.Children.Add(Button1);
Button1.Padding = new Thickness(0);
Button1.BackgroundColor = Color.Transparent;
Button1.WidthRequest = 40;
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
}
if(!string.IsNullOrWhiteSpace(button2))
{
Button2 = new ExtendedButton { Image = button2 };
_buttonStackLayout.Children.Add(Button2);
Button2.Padding = new Thickness(0);
Button2.BackgroundColor = Color.Transparent;
Button2.WidthRequest = 40;
Button2.VerticalOptions = LayoutOptions.FillAndExpand;
}
}
if(Device.RuntimePlatform == Device.Android)
{
var deviceInfo = Resolver.Resolve<IDeviceInfoService>();
if(useLabelAsPlaceholder)
{
if(deviceInfo.Version < 21)
{
Entry.Margin = new Thickness(-9, 1, -9, 0);
}
else if(deviceInfo.Version == 21)
{
Entry.Margin = new Thickness(0, 4, 0, -4);
}
}
else
{
Entry.AdjustMarginsForDevice();
}
if(containerPadding == null)
{
imageStackLayout.AdjustPaddingForDevice();
}
}
else if(Device.RuntimePlatform == Device.UWP)
{
if(_buttonStackLayout != null)
{
_buttonStackLayout.Spacing = 0;
}
}
View = imageStackLayout;
}
public Label Label { get; private set; }
public ExtendedEntry Entry { get; private set; }
public ExtendedButton Button1 { get; private set; }
public ExtendedButton Button2 { get; private set; }
public VisualElement NextElement
{
get => _nextElement;
set
{
_nextElement = value;
if(_nextElement != null && Entry != null)
{
Entry.TargetReturnType = Enums.ReturnType.Next;
}
else if(Entry != null)
{
Entry.TargetReturnType = null;
}
}
}
public Dictionary<string, object> MetaData { get; set; }
public void InitEvents()
{
if(_nextElement != null)
{
Entry.Completed += Entry_Completed;
}
if(_tgr != null)
{
_tgr.Tapped += Tgr_Tapped;
}
Tapped += FormEntryCell_Tapped;
}
private void Tgr_Tapped(object sender, EventArgs e)
{
Entry.Focus();
}
private void FormEntryCell_Tapped(object sender, EventArgs e)
{
Entry.Focus();
}
private void Entry_Completed(object sender, EventArgs e)
{
_nextElement?.Focus();
}
public void Dispose()
{
if(_tgr != null)
{
_tgr.Tapped -= Tgr_Tapped;
}
Tapped -= FormEntryCell_Tapped;
Entry.Completed -= Entry_Completed;
}
}
}

View File

@@ -1,65 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FormPickerCell : ExtendedViewCell
{
public FormPickerCell(string labelText, string[] pickerItems)
{
Label = new Label
{
Text = labelText,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
TextColor = Color.FromHex("777777")
};
Picker = new ExtendedPicker
{
HasBorder = false
};
foreach(var item in pickerItems)
{
Picker.Items.Add(item);
}
Picker.SelectedIndex = 0;
var stackLayout = new StackLayout
{
Padding = new Thickness(15, 10),
VerticalOptions = LayoutOptions.CenterAndExpand
};
stackLayout.Children.Add(Label);
stackLayout.Children.Add(Picker);
if(Device.RuntimePlatform == Device.Android)
{
stackLayout.Spacing = 0;
}
Picker.AdjustMarginsForDevice();
stackLayout.AdjustPaddingForDevice();
View = stackLayout;
}
public Label Label { get; private set; }
public ExtendedPicker Picker { get; private set; }
private void FormPickerCell_Tapped(object sender, EventArgs e)
{
Picker.Focus();
}
public void InitEvents()
{
Tapped += FormPickerCell_Tapped;
}
public void Dispose()
{
Tapped -= FormPickerCell_Tapped;
}
}
}

View File

@@ -1,47 +0,0 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FormSwitchCell : ExtendedViewCell
{
public FormSwitchCell(string labelText, string button1 = null)
{
Label = new Label
{
Text = labelText,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalTextAlignment = TextAlignment.Center,
TextColor = Color.Black,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
};
Switch = new Switch
{
VerticalOptions = LayoutOptions.Center
};
var stackLayout = new StackLayout
{
Padding = new Thickness(15, 5),
Orientation = StackOrientation.Horizontal,
Children = { Label, Switch }
};
stackLayout.AdjustPaddingForDevice();
if(!string.IsNullOrWhiteSpace(button1))
{
Button1 = new ExtendedButton { Image = button1 };
stackLayout.Children.Add(Button1);
Button1.BackgroundColor = Color.Transparent;
Button1.Padding = new Thickness(0);
Button1.WidthRequest = 40;
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
}
View = stackLayout;
}
public Switch Switch { get; private set; }
public Label Label { get; set; }
public ExtendedButton Button1 { get; set; }
}
}

View File

@@ -1,34 +0,0 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class HybridWebView : View
{
private Action<string> _func;
public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: nameof(Uri),
returnType: typeof(string), declaringType: typeof(HybridWebView), defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
_func = callback;
}
public void Cleanup()
{
_func = null;
}
public void InvokeAction(string data)
{
_func?.Invoke(data);
}
}
}

View File

@@ -1,94 +0,0 @@
using FFImageLoading.Forms;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class LabeledDetailCell : ExtendedViewCell
{
public LabeledDetailCell()
{
Icon = new CachedImage
{
WidthRequest = 20,
HeightRequest = 20,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
ErrorPlaceholder = "login.png",
CacheDuration = TimeSpan.FromDays(30),
BitmapOptimizations = true
};
Label = new Label
{
LineBreakMode = LineBreakMode.TailTruncation,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
};
Detail = new Label
{
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
LineBreakMode = LineBreakMode.TailTruncation,
Style = (Style)Application.Current.Resources["text-muted"]
};
LabelIcon = new CachedImage
{
WidthRequest = 16,
HeightRequest = 16,
HorizontalOptions = LayoutOptions.Start,
Margin = new Thickness(5, 0, 0, 0)
};
LabelIcon2 = new CachedImage
{
WidthRequest = 16,
HeightRequest = 16,
HorizontalOptions = LayoutOptions.Start,
Margin = new Thickness(5, 0, 0, 0)
};
Button = new ExtendedButton
{
WidthRequest = 60
};
var grid = new Grid
{
ColumnSpacing = 0,
RowSpacing = 0,
Padding = new Thickness(3, 3, 0, 3)
};
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40, GridUnitType.Absolute) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(60, GridUnitType.Absolute) });
grid.Children.Add(Icon, 0, 0);
grid.Children.Add(Label, 1, 0);
grid.Children.Add(Detail, 1, 1);
grid.Children.Add(LabelIcon, 2, 0);
grid.Children.Add(LabelIcon2, 3, 0);
grid.Children.Add(Button, 4, 0);
Grid.SetRowSpan(Icon, 2);
Grid.SetRowSpan(Button, 2);
Grid.SetColumnSpan(Detail, 3);
if(Device.RuntimePlatform == Device.Android)
{
Label.TextColor = Color.Black;
}
View = grid;
}
public CachedImage Icon { get; private set; }
public Label Label { get; private set; }
public Label Detail { get; private set; }
public CachedImage LabelIcon { get; private set; }
public CachedImage LabelIcon2 { get; private set; }
public Button Button { get; private set; }
}
}

View File

@@ -1,59 +0,0 @@
using FFImageLoading.Forms;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class LabeledRightDetailCell : ExtendedViewCell
{
public LabeledRightDetailCell(bool showIcon = true)
{
Label = new Label
{
LineBreakMode = LineBreakMode.TailTruncation,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
HorizontalOptions = LayoutOptions.StartAndExpand,
};
Detail = new Label
{
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center
};
StackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Padding = new Thickness(15, 10),
Children = { Label, Detail }
};
if(showIcon)
{
Icon = new CachedImage
{
WidthRequest = 16,
HeightRequest = 16,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
Margin = new Thickness(5, 0, 0, 0)
};
StackLayout.Children.Add(Icon);
}
if(Device.RuntimePlatform == Device.Android)
{
Label.TextColor = Color.Black;
}
View = StackLayout;
}
public Label Label { get; private set; }
public Label Detail { get; private set; }
public CachedImage Icon { get; private set; }
public StackLayout StackLayout { get; private set; }
}
}

View File

@@ -1,138 +0,0 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class LabeledValueCell : ExtendedViewCell
{
public LabeledValueCell(
string labelText = null,
string valueText = null,
string button1Image = null,
string button2Image = null,
string subText = null)
{
var containerStackLayout = new StackLayout
{
Padding = new Thickness(15, 10),
Orientation = StackOrientation.Horizontal
};
var labelValueStackLayout = new StackLayout
{
HorizontalOptions = LayoutOptions.StartAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand
};
if(labelText != null)
{
Label = new Label
{
Text = labelText,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"]
};
labelValueStackLayout.Children.Add(Label);
}
Value = new Label
{
Text = valueText,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
LineBreakMode = LineBreakMode.TailTruncation
};
if(Device.RuntimePlatform == Device.Android)
{
Value.TextColor = Color.Black;
}
labelValueStackLayout.Children.Add(Value);
containerStackLayout.Children.Add(labelValueStackLayout);
var buttonStackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 5
};
if(subText != null)
{
Sub = new Label
{
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center
};
buttonStackLayout.Children.Add(Sub);
}
if(button1Image != null)
{
Button1 = new ExtendedButton
{
Image = button1Image,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.FillAndExpand,
Margin = new Thickness(0),
Padding = new Thickness(0),
BackgroundColor = Color.Transparent,
WidthRequest = 40
};
buttonStackLayout.Children.Add(Button1);
}
if(button2Image != null)
{
Button2 = new ExtendedButton
{
Image = button2Image,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.FillAndExpand,
Margin = new Thickness(0),
Padding = new Thickness(0),
BackgroundColor = Color.Transparent,
WidthRequest = 40
};
buttonStackLayout.Children.Add(Button2);
}
if(Device.RuntimePlatform == Device.Android)
{
containerStackLayout.AdjustPaddingForDevice();
}
else if(Device.RuntimePlatform == Device.UWP)
{
buttonStackLayout.Spacing = 0;
if(Button1 != null)
{
Button1.BackgroundColor = Color.Transparent;
}
if(Button2 != null)
{
Button2.BackgroundColor = Color.Transparent;
}
}
if(Sub != null && Button1 != null)
{
Sub.Margin = new Thickness(0, 0, 10, 0);
}
containerStackLayout.Children.Add(buttonStackLayout);
View = containerStackLayout;
}
public Label Label { get; private set; }
public Label Value { get; private set; }
public Label Sub { get; private set; }
public ExtendedButton Button1 { get; private set; }
public ExtendedButton Button2 { get; private set; }
}
}

View File

@@ -1,61 +0,0 @@
using Bit.App.Utilities;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class PinControl
{
public EventHandler OnPinEntered;
public PinControl()
{
Label = new Label
{
HorizontalTextAlignment = TextAlignment.Center,
FontSize = 35,
FontFamily = Helpers.OnPlatform(iOS: "Menlo-Regular", Android: "monospace", Windows: "Courier")
};
Entry = new ExtendedEntry
{
Keyboard = Keyboard.Numeric,
TargetMaxLength = 4,
HideCursor = true,
NumbersOnly = true
};
Entry.BackgroundColor = Entry.TextColor = Color.Transparent;
if(Device.RuntimePlatform == Device.Android)
{
Label.TextColor = Color.Black;
}
else
{
Entry.Margin = new Thickness(0, int.MaxValue, 0, 0);
}
}
public Label Label { get; set; }
public ExtendedEntry Entry { get; set; }
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
if(e.NewTextValue.Length >= 4)
{
OnPinEntered.Invoke(this, null);
}
}
public void InitEvents()
{
Entry.TextChanged += Entry_TextChanged;
}
public void Dispose()
{
Entry.TextChanged -= Entry_TextChanged;
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class RedrawableStackLayout : StackLayout
{
private DateTime _lastRedraw = DateTime.MinValue;
private TimeSpan _redrawThreshold = TimeSpan.FromMilliseconds(1000);
public async Task RedrawIfNeededAsync(int delay = 0, bool force = false)
{
var now = DateTime.UtcNow;
if(Device.RuntimePlatform == Device.iOS && (force || (now - _lastRedraw) > _redrawThreshold))
{
_lastRedraw = now;
if(delay > 0)
{
await Task.Delay(delay);
}
InvalidateLayout();
}
}
}
}

View File

@@ -1,45 +0,0 @@
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class SectionHeaderViewCell : ExtendedViewCell
{
public SectionHeaderViewCell(string bindingName, string countBindingName = null, Thickness? padding = null)
{
var label = new Label
{
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"],
VerticalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.StartAndExpand
};
label.SetBinding(Label.TextProperty, bindingName);
var stackLayout = new StackLayout
{
Padding = padding ?? new Thickness(16, 8),
Children = { label },
Orientation = StackOrientation.Horizontal
};
if(!string.IsNullOrWhiteSpace(countBindingName))
{
var countLabel = new Label
{
LineBreakMode = LineBreakMode.NoWrap,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.End,
VerticalTextAlignment = TextAlignment.Center
};
countLabel.SetBinding(Label.TextProperty, countBindingName);
stackLayout.Children.Add(countLabel);
}
View = stackLayout;
BackgroundColor = Color.FromHex("efeff4");
}
}
}

View File

@@ -1,83 +0,0 @@
using Bit.App.Utilities;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class StepperCell : ExtendedViewCell
{
private Action _changedAction;
public StepperCell(string labelText, double value, double min, double max, double increment, Action changed = null)
{
_changedAction = changed;
Label = new Label
{
Text = labelText,
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.CenterAndExpand,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
};
StepperValueLabel = new Label
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalTextAlignment = TextAlignment.Start,
Text = value.ToString(),
Style = (Style)Application.Current.Resources["text-muted"],
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
};
Stepper = new Stepper
{
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.CenterAndExpand,
Minimum = min,
Maximum = max,
Increment = increment,
Value = value
};
var stackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Children = { Label, StepperValueLabel, Stepper },
Spacing = 15,
Padding = Helpers.OnPlatform(
iOS: new Thickness(15, 8),
Android: new Thickness(15, 2),
Windows: new Thickness(15, 8))
};
if(Device.RuntimePlatform == Device.Android)
{
Label.TextColor = Color.Black;
}
stackLayout.AdjustPaddingForDevice();
View = stackLayout;
}
public Label Label { get; private set; }
public Label StepperValueLabel { get; private set; }
public Stepper Stepper { get; private set; }
private void Stepper_ValueChanged(object sender, ValueChangedEventArgs e)
{
StepperValueLabel.Text = e.NewValue.ToString();
_changedAction?.Invoke();
}
public void InitEvents()
{
Stepper.ValueChanged += Stepper_ValueChanged;
}
public void Dispose()
{
Stepper.ValueChanged -= Stepper_ValueChanged;
}
}
}

View File

@@ -1,22 +0,0 @@
using Bit.App.Models.Page;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class VaultAttachmentsViewCell : LabeledRightDetailCell
{
public VaultAttachmentsViewCell()
{
Label.SetBinding(Label.TextProperty, nameof(VaultAttachmentsPageModel.Attachment.Name));
Detail.SetBinding(Label.TextProperty, nameof(VaultAttachmentsPageModel.Attachment.SizeName));
Icon.Source = "trash";
Detail.MinimumWidthRequest = 100;
BackgroundColor = Color.White;
if(Device.RuntimePlatform == Device.iOS)
{
StackLayout.BackgroundColor = Color.White;
}
}
}
}

View File

@@ -1,74 +0,0 @@
using Bit.App.Models.Page;
using FFImageLoading.Forms;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class VaultGroupingViewCell : ExtendedViewCell
{
public VaultGroupingViewCell()
{
Icon = new CachedImage
{
WidthRequest = 20,
HeightRequest = 20,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Source = "folder.png",
Margin = new Thickness(0, 0, 10, 0)
};
Label = new Label
{
LineBreakMode = LineBreakMode.TailTruncation,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
HorizontalOptions = LayoutOptions.StartAndExpand
};
Label.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Name)));
CountLabel = new Label
{
LineBreakMode = LineBreakMode.NoWrap,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.End
};
CountLabel.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Count)));
CountLabel.SetBinding(VisualElement.IsVisibleProperty, string.Format("{0}.Node.{1}",
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.ShowCount)));
var stackLayout = new StackLayout
{
Spacing = 0,
Padding = new Thickness(16, 10),
Children = { Icon, Label, CountLabel },
Orientation = StackOrientation.Horizontal
};
if(Device.RuntimePlatform == Device.Android)
{
Label.TextColor = Color.Black;
}
View = stackLayout;
BackgroundColor = Color.White;
}
public CachedImage Icon { get; private set; }
public Label Label { get; private set; }
public Label CountLabel { get; private set; }
protected override void OnBindingContextChanged()
{
if(BindingContext is VaultListPageModel.GroupingOrCipher model)
{
Icon.Source = model.Grouping.Node.Folder ?
$"folder{(model.Grouping.Node.Id == null ? "_o" : string.Empty)}.png" : "cube.png";
}
base.OnBindingContextChanged();
}
}
}

View File

@@ -1,84 +0,0 @@
using Bit.App.Models.Page;
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class VaultListViewCell : LabeledDetailCell
{
public static readonly BindableProperty CipherParameterProperty = BindableProperty.Create(nameof(CipherParameter),
typeof(VaultListPageModel.Cipher), typeof(VaultListViewCell), null);
public static readonly BindableProperty GroupingOrCipherParameterProperty =
BindableProperty.Create(nameof(GroupingOrCipherParameter), typeof(VaultListPageModel.GroupingOrCipher),
typeof(VaultListViewCell), null);
public VaultListViewCell(Action<VaultListPageModel.Cipher> moreClickedAction, bool groupingOrCipherBinding = false)
{
string bindingPrefix = null;
if(groupingOrCipherBinding)
{
SetBinding(GroupingOrCipherParameterProperty, new Binding("."));
bindingPrefix = string.Concat(nameof(VaultListPageModel.GroupingOrCipher.Cipher), ".");
Button.Command = new Command(() => moreClickedAction?.Invoke(GroupingOrCipherParameter?.Cipher));
}
else
{
SetBinding(CipherParameterProperty, new Binding("."));
Button.Command = new Command(() => moreClickedAction?.Invoke(CipherParameter));
}
Label.SetBinding(Label.TextProperty, bindingPrefix + nameof(VaultListPageModel.Cipher.Name));
Detail.SetBinding(Label.TextProperty, bindingPrefix + nameof(VaultListPageModel.Cipher.Subtitle));
LabelIcon.SetBinding(VisualElement.IsVisibleProperty,
bindingPrefix + nameof(VaultListPageModel.Cipher.Shared));
LabelIcon2.SetBinding(VisualElement.IsVisibleProperty,
bindingPrefix + nameof(VaultListPageModel.Cipher.HasAttachments));
Button.Image = "more.png";
Button.BackgroundColor = Color.Transparent;
LabelIcon.Source = "share.png";
LabelIcon2.Source = "paperclip.png";
BackgroundColor = Color.White;
}
public VaultListPageModel.Cipher CipherParameter
{
get { return GetValue(CipherParameterProperty) as VaultListPageModel.Cipher; }
set { SetValue(CipherParameterProperty, value); }
}
public VaultListPageModel.GroupingOrCipher GroupingOrCipherParameter
{
get { return GetValue(GroupingOrCipherParameterProperty) as VaultListPageModel.GroupingOrCipher; }
set { SetValue(GroupingOrCipherParameterProperty, value); }
}
protected override void OnBindingContextChanged()
{
Icon.Source = null;
VaultListPageModel.Cipher cipher = null;
if(BindingContext is VaultListPageModel.Cipher item)
{
cipher = item;
}
else if(BindingContext is VaultListPageModel.GroupingOrCipher groupingOrCipherItem)
{
cipher = groupingOrCipherItem.Cipher;
}
if(cipher != null)
{
if(cipher.Type == Enums.CipherType.Login)
{
Icon.LoadingPlaceholder = "login.png";
}
Icon.Source = cipher.Icon;
}
base.OnBindingContextChanged();
}
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Enums
{
public enum CipherType : short
{
// Folder deprecated
//Folder = 0,
Login = 1,
SecureNote = 2,
Card = 3,
Identity = 4
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Enums
{
public enum DeviceType
{
Android = 0,
iOS = 1,
UWP = 16
}
}

View File

@@ -1,13 +0,0 @@
namespace Bit.App.Enums
{
public enum EncryptionType : byte
{
AesCbc256_B64 = 0,
AesCbc128_HmacSha256_B64 = 1,
AesCbc256_HmacSha256_B64 = 2,
Rsa2048_OaepSha256_B64 = 3,
Rsa2048_OaepSha1_B64 = 4,
Rsa2048_OaepSha256_HmacSha256_B64 = 5,
Rsa2048_OaepSha1_HmacSha256_B64 = 6
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Enums
{
public enum FieldType : byte
{
Text = 0,
Hidden = 1,
Boolean = 2
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Enums
{
public enum KdfType : short
{
PBKDF2_SHA256 = 0
}
}

View File

@@ -1,10 +0,0 @@
namespace Bit.App.Enums
{
public enum LockType : short
{
None = 0,
Fingerprint = 1,
PIN = 2,
Password = 3
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Enums
{
public enum OrganizationUserStatusType : byte
{
Invited = 0,
Accepted = 1,
Confirmed = 2
}
}

View File

@@ -1,9 +0,0 @@
namespace Bit.App.Enums
{
public enum OrganizationUserType : byte
{
Owner = 0,
Admin = 1,
User = 2
}
}

View File

@@ -1,20 +0,0 @@
namespace Bit.App.Enums
{
public enum PushType : short
{
SyncCipherUpdate = 0,
SyncCipherCreate = 1,
SyncLoginDelete = 2,
SyncFolderDelete = 3,
SyncCiphers = 4,
SyncVault = 5,
SyncOrgKeys = 6,
SyncFolderCreate = 7,
SyncFolderUpdate = 8,
SyncCipherDelete = 9,
SyncSettings = 10,
LogOut = 11,
}
}

View File

@@ -1,11 +0,0 @@
namespace Bit.App.Enums
{
public enum ReturnType
{
Done,
Go,
Next,
Search,
Send
}
}

View File

@@ -1,7 +0,0 @@
namespace Bit.App.Enums
{
public enum SecureNoteType : byte
{
Generic = 0
}
}

View File

@@ -1,13 +0,0 @@
namespace Bit.App.Enums
{
public enum TwoFactorProviderType : byte
{
Authenticator = 0,
Email = 1,
Duo = 2,
YubiKey = 3,
U2f = 4,
Remember = 5,
OrganizationDuo = 6
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Enums
{
public enum UriMatchType : byte
{
Domain = 0,
Host = 1,
StartsWith = 2,
Exact = 3,
RegularExpression = 4,
Never = 5
}
}

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; }
}
}

Some files were not shown because too many files have changed in this diff Show More