1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-18 17:23:18 +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,21 +0,0 @@
using Bit.App.Abstractions;
using System;
using UIKit;
using XLabs.Ioc;
namespace Bit.iOS.Core.Controllers
{
public class ExtendedUITableViewController : UITableViewController
{
public ExtendedUITableViewController(IntPtr handle)
: base(handle)
{ }
public override void ViewDidAppear(bool animated)
{
var googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
googleAnalyticsService.TrackPage(GetType().Name);
base.ViewDidAppear(animated);
}
}
}

View File

@@ -1,21 +0,0 @@
using System;
using UIKit;
using Bit.App.Abstractions;
using XLabs.Ioc;
namespace Bit.iOS.Core.Controllers
{
public class ExtendedUIViewController : UIViewController
{
public ExtendedUIViewController(IntPtr handle)
: base(handle)
{ }
public override void ViewDidAppear(bool animated)
{
var googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
googleAnalyticsService.TrackPage(GetType().Name);
base.ViewDidAppear(animated);
}
}
}

View File

@@ -1,86 +0,0 @@
using System;
using UIKit;
using XLabs.Ioc;
using Plugin.Fingerprint.Abstractions;
using System.Threading.Tasks;
using Bit.iOS.Core.Controllers;
using Bit.App.Resources;
using Bit.App.Abstractions;
namespace Bit.iOS.Core.Controllers
{
public abstract class LockFingerprintViewController : ExtendedUIViewController
{
private IAppSettingsService _appSettingsService;
private IFingerprint _fingerprint;
private IDeviceInfoService _deviceInfo;
public LockFingerprintViewController(IntPtr handle) : base(handle)
{ }
public abstract UINavigationItem BaseNavItem { get; }
public abstract UIBarButtonItem BaseCancelButton { get; }
public abstract UIButton BaseUseButton { get; }
public abstract UIButton BaseFingerprintButton { get; }
public abstract Action Success { get; }
public override void ViewWillAppear(bool animated)
{
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
base.ViewWillAppear(animated);
}
public override void ViewDidLoad()
{
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
_fingerprint = Resolver.Resolve<IFingerprint>();
_deviceInfo = Resolver.Resolve<IDeviceInfoService>();
BaseNavItem.Title = _deviceInfo.HasFaceIdSupport ? AppResources.VerifyFaceID : AppResources.VerifyFingerprint;
BaseCancelButton.Title = AppResources.Cancel;
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
BaseUseButton.SetTitle(_deviceInfo.HasFaceIdSupport ? AppResources.UseFaceIDToUnlock :
AppResources.UseFingerprintToUnlock, UIControlState.Normal);
var descriptor = UIFontDescriptor.PreferredBody;
BaseUseButton.Font = UIFont.FromDescriptor(descriptor, descriptor.PointSize);
BaseUseButton.BackgroundColor = new UIColor(red: 0.24f, green: 0.55f, blue: 0.74f, alpha: 1.0f);
BaseUseButton.TintColor = UIColor.White;
BaseUseButton.TouchUpInside += UseButton_TouchUpInside;
BaseFingerprintButton.SetImage(new UIImage(_deviceInfo.HasFaceIdSupport ? "smile.png" : "fingerprint.png"),
UIControlState.Normal);
base.ViewDidLoad();
}
private void UseButton_TouchUpInside(object sender, EventArgs e)
{
var task = CheckFingerprintAsync();
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
var task = CheckFingerprintAsync();
}
public async Task CheckFingerprintAsync()
{
var fingerprintRequest = new AuthenticationRequestConfiguration(
_deviceInfo.HasFaceIdSupport ? AppResources.FaceIDDirection : AppResources.FingerprintDirection)
{
AllowAlternativeAuthentication = true,
CancelTitle = AppResources.Cancel,
FallbackTitle = AppResources.LogOut
};
var result = await _fingerprint.AuthenticateAsync(fingerprintRequest);
if(result.Authenticated)
{
_appSettingsService.Locked = false;
Success();
}
}
}
}

View File

@@ -1,178 +0,0 @@
using System;
using UIKit;
using XLabs.Ioc;
using Foundation;
using Bit.iOS.Core.Views;
using Bit.App.Resources;
using Bit.iOS.Core.Utilities;
using Bit.App.Abstractions;
using System.Linq;
using Bit.iOS.Core.Controllers;
namespace Bit.iOS.Core.Controllers
{
public abstract class LockPasswordViewController : ExtendedUITableViewController
{
private IAppSettingsService _appSettingsService;
private IAuthService _authService;
private ICryptoService _cryptoService;
public LockPasswordViewController(IntPtr handle) : base(handle)
{ }
public abstract UINavigationItem BaseNavItem { get; }
public abstract UIBarButtonItem BaseCancelButton { get; }
public abstract UIBarButtonItem BaseSubmitButton { get; }
public abstract Action Success { get; }
public FormEntryTableViewCell MasterPasswordCell { get; set; } = new FormEntryTableViewCell(
AppResources.MasterPassword, useLabelAsPlaceholder: true);
public override void ViewWillAppear(bool animated)
{
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
base.ViewWillAppear(animated);
}
public override void ViewDidLoad()
{
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
_authService = Resolver.Resolve<IAuthService>();
_cryptoService = Resolver.Resolve<ICryptoService>();
BaseNavItem.Title = AppResources.VerifyMasterPassword;
BaseCancelButton.Title = AppResources.Cancel;
BaseSubmitButton.Title = AppResources.Submit;
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
var descriptor = UIFontDescriptor.PreferredBody;
MasterPasswordCell.TextField.SecureTextEntry = true;
MasterPasswordCell.TextField.ReturnKeyType = UIReturnKeyType.Go;
MasterPasswordCell.TextField.ShouldReturn += (UITextField tf) =>
{
CheckPassword();
return true;
};
TableView.RowHeight = UITableView.AutomaticDimension;
TableView.EstimatedRowHeight = 70;
TableView.Source = new TableSource(this);
TableView.AllowsSelection = true;
base.ViewDidLoad();
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
MasterPasswordCell.TextField.BecomeFirstResponder();
}
protected void CheckPassword()
{
if(string.IsNullOrWhiteSpace(MasterPasswordCell.TextField.Text))
{
var alert = Dialogs.CreateAlert(AppResources.AnErrorHasOccurred,
string.Format(AppResources.ValidationFieldRequired, AppResources.MasterPassword), AppResources.Ok);
PresentViewController(alert, true, null);
return;
}
var key = _cryptoService.MakeKeyFromPassword(MasterPasswordCell.TextField.Text, _authService.Email,
_authService.Kdf, _authService.KdfIterations);
if(key.Key.SequenceEqual(_cryptoService.Key.Key))
{
_appSettingsService.Locked = false;
MasterPasswordCell.TextField.ResignFirstResponder();
Success();
}
else
{
// TODO: keep track of invalid attempts and logout?
var alert = Dialogs.CreateAlert(AppResources.AnErrorHasOccurred,
string.Format(null, AppResources.InvalidMasterPassword), AppResources.Ok, (a) =>
{
MasterPasswordCell.TextField.Text = string.Empty;
MasterPasswordCell.TextField.BecomeFirstResponder();
});
PresentViewController(alert, true, null);
}
}
public class TableSource : UITableViewSource
{
private LockPasswordViewController _controller;
public TableSource(LockPasswordViewController controller)
{
_controller = controller;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
if(indexPath.Section == 0)
{
if(indexPath.Row == 0)
{
return _controller.MasterPasswordCell;
}
}
return new UITableViewCell();
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}
public override nint NumberOfSections(UITableView tableView)
{
return 1;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
if(section == 0)
{
return 1;
}
return 0;
}
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
{
return UITableView.AutomaticDimension;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return null;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
tableView.DeselectRow(indexPath, true);
tableView.EndEditing(true);
var cell = tableView.CellAt(indexPath);
if(cell == null)
{
return;
}
var selectableCell = cell as ISelectable;
if(selectableCell != null)
{
selectableCell.Select();
}
}
}
}
}

View File

@@ -1,102 +0,0 @@
using System;
using UIKit;
using XLabs.Ioc;
using Bit.App.Abstractions;
using Bit.iOS.Core.Utilities;
using Bit.App.Resources;
using System.Diagnostics;
using Bit.iOS.Core.Controllers;
namespace Bit.iOS.Core.Controllers
{
public abstract class LockPinViewController : ExtendedUIViewController
{
private IAppSettingsService _appSettingsService;
private IAuthService _authService;
public LockPinViewController(IntPtr handle) : base(handle)
{ }
public abstract UINavigationItem BaseNavItem { get; }
public abstract UIBarButtonItem BaseCancelButton { get; }
public abstract UILabel BasePinLabel { get; }
public abstract UILabel BaseInstructionLabel { get; }
public abstract UITextField BasePinTextField { get; }
public abstract Action Success { get; }
public override void ViewWillAppear(bool animated)
{
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
base.ViewWillAppear(animated);
}
public override void ViewDidLoad()
{
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
_authService = Resolver.Resolve<IAuthService>();
BaseNavItem.Title = AppResources.VerifyPIN;
BaseCancelButton.Title = AppResources.Cancel;
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
var descriptor = UIFontDescriptor.PreferredBody;
BasePinLabel.Font = UIFont.FromName("Menlo-Regular", 35);
BaseInstructionLabel.Text = AppResources.EnterPIN;
BaseInstructionLabel.LineBreakMode = UILineBreakMode.WordWrap;
BaseInstructionLabel.Lines = 0;
BaseInstructionLabel.Font = UIFont.FromDescriptor(descriptor, descriptor.PointSize * 0.8f);
BaseInstructionLabel.TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f);
BasePinTextField.EditingChanged += PinTextField_EditingChanged;
base.ViewDidLoad();
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
BasePinTextField.BecomeFirstResponder();
}
private void PinTextField_EditingChanged(object sender, EventArgs e)
{
SetLabelText();
if(BasePinTextField.Text.Length >= 4)
{
if(BasePinTextField.Text == _authService.PIN)
{
Debug.WriteLine("BW Log, Start Dismiss PIN controller.");
_appSettingsService.Locked = false;
BasePinTextField.ResignFirstResponder();
Success();
}
else
{
// TODO: keep track of invalid attempts and logout?
var alert = Dialogs.CreateAlert(null, AppResources.InvalidPIN, AppResources.Ok, (a) =>
{
BasePinTextField.Text = string.Empty;
SetLabelText();
BasePinTextField.BecomeFirstResponder();
});
PresentViewController(alert, true, null);
}
}
}
private void SetLabelText()
{
var newText = string.Empty;
for(int i = 0; i < 4; i++)
{
newText += BasePinTextField.Text.Length <= i ? "- " : "• ";
}
BasePinLabel.Text = newText.TrimEnd();
}
}
}

View File

@@ -1,338 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.iOS.Core.Views;
using Foundation;
using UIKit;
using XLabs.Ioc;
using Bit.App;
using Plugin.Connectivity.Abstractions;
using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Models;
using System.Threading.Tasks;
using AuthenticationServices;
namespace Bit.iOS.Core.Controllers
{
public abstract class LoginAddViewController : ExtendedUITableViewController
{
private ICipherService _cipherService;
private IFolderService _folderService;
private IConnectivity _connectivity;
private IEnumerable<Folder> _folders;
protected IGoogleAnalyticsService _googleAnalyticsService;
public LoginAddViewController(IntPtr handle) : base(handle)
{
}
public AppExtensionContext Context { get; set; }
public FormEntryTableViewCell NameCell { get; set; } = new FormEntryTableViewCell(AppResources.Name);
public FormEntryTableViewCell UsernameCell { get; set; } = new FormEntryTableViewCell(AppResources.Username);
public FormEntryTableViewCell PasswordCell { get; set; } = new FormEntryTableViewCell(AppResources.Password);
public UITableViewCell GeneratePasswordCell { get; set; } = new UITableViewCell(UITableViewCellStyle.Subtitle, "GeneratePasswordCell");
public FormEntryTableViewCell UriCell { get; set; } = new FormEntryTableViewCell(AppResources.URI);
public SwitchTableViewCell FavoriteCell { get; set; } = new SwitchTableViewCell(AppResources.Favorite);
public FormEntryTableViewCell NotesCell { get; set; } = new FormEntryTableViewCell(useTextView: true, height: 180);
public PickerTableViewCell FolderCell { get; set; } = new PickerTableViewCell(AppResources.Folder);
public abstract UINavigationItem BaseNavItem { get; }
public abstract UIBarButtonItem BaseCancelButton { get; }
public abstract UIBarButtonItem BaseSaveButton { get; }
public abstract Action Success { get; }
public override void ViewWillAppear(bool animated)
{
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
base.ViewWillAppear(animated);
}
public override void ViewDidLoad()
{
_cipherService = Resolver.Resolve<ICipherService>();
_connectivity = Resolver.Resolve<IConnectivity>();
_folderService = Resolver.Resolve<IFolderService>();
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
BaseNavItem.Title = AppResources.AddItem;
BaseCancelButton.Title = AppResources.Cancel;
BaseSaveButton.Title = AppResources.Save;
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
NameCell.TextField.Text = Context?.Uri?.Host ?? string.Empty;
NameCell.TextField.ReturnKeyType = UIReturnKeyType.Next;
NameCell.TextField.ShouldReturn += (UITextField tf) =>
{
UsernameCell.TextField.BecomeFirstResponder();
return true;
};
UsernameCell.TextField.AutocapitalizationType = UITextAutocapitalizationType.None;
UsernameCell.TextField.AutocorrectionType = UITextAutocorrectionType.No;
UsernameCell.TextField.SpellCheckingType = UITextSpellCheckingType.No;
UsernameCell.TextField.ReturnKeyType = UIReturnKeyType.Next;
UsernameCell.TextField.ShouldReturn += (UITextField tf) =>
{
PasswordCell.TextField.BecomeFirstResponder();
return true;
};
PasswordCell.TextField.SecureTextEntry = true;
PasswordCell.TextField.ReturnKeyType = UIReturnKeyType.Next;
PasswordCell.TextField.ShouldReturn += (UITextField tf) =>
{
UriCell.TextField.BecomeFirstResponder();
return true;
};
GeneratePasswordCell.TextLabel.Text = AppResources.GeneratePassword;
GeneratePasswordCell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
UriCell.TextField.Text = Context?.UrlString ?? string.Empty;
UriCell.TextField.KeyboardType = UIKeyboardType.Url;
UriCell.TextField.ReturnKeyType = UIReturnKeyType.Next;
UriCell.TextField.ShouldReturn += (UITextField tf) =>
{
NotesCell.TextView.BecomeFirstResponder();
return true;
};
_folders = _folderService.GetAllAsync().GetAwaiter().GetResult();
var folderNames = _folders.Select(s => s.Name.Decrypt()).OrderBy(s => s).ToList();
folderNames.Insert(0, AppResources.FolderNone);
FolderCell.Items = folderNames;
TableView.RowHeight = UITableView.AutomaticDimension;
TableView.EstimatedRowHeight = 70;
TableView.Source = new TableSource(this);
TableView.AllowsSelection = true;
base.ViewDidLoad();
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
}
protected async Task SaveAsync()
{
if(!_connectivity.IsConnected)
{
AlertNoConnection();
return;
}
if(string.IsNullOrWhiteSpace(PasswordCell.TextField.Text))
{
DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Password), AppResources.Ok);
return;
}
if(string.IsNullOrWhiteSpace(NameCell.TextField.Text))
{
DisplayAlert(AppResources.AnErrorHasOccurred, string.Format(AppResources.ValidationFieldRequired, AppResources.Name), AppResources.Ok);
return;
}
var cipher = new Cipher
{
Name = string.IsNullOrWhiteSpace(NameCell.TextField.Text) ? null : NameCell.TextField.Text.Encrypt(),
Notes = string.IsNullOrWhiteSpace(NotesCell.TextView.Text) ? null : NotesCell.TextView.Text.Encrypt(),
Favorite = FavoriteCell.Switch.On,
FolderId = FolderCell.SelectedIndex == 0 ? null : _folders.ElementAtOrDefault(FolderCell.SelectedIndex - 1)?.Id,
Type = App.Enums.CipherType.Login,
Login = new Login
{
Uris = null,
Username = string.IsNullOrWhiteSpace(UsernameCell.TextField.Text) ? null : UsernameCell.TextField.Text.Encrypt(),
Password = string.IsNullOrWhiteSpace(PasswordCell.TextField.Text) ? null : PasswordCell.TextField.Text.Encrypt()
}
};
if(!string.IsNullOrWhiteSpace(UriCell.TextField.Text))
{
cipher.Login.Uris = new List<LoginUri>
{
new LoginUri
{
Uri = UriCell.TextField.Text.Encrypt()
}
};
}
var saveTask = _cipherService.SaveAsync(cipher);
var loadingAlert = Dialogs.CreateLoadingAlert(AppResources.Saving);
PresentViewController(loadingAlert, true, null);
await saveTask;
await loadingAlert.DismissViewControllerAsync(true);
if(saveTask.Result.Succeeded)
{
if (await ASHelpers.IdentitiesCanIncremental())
{
var identity = await ASHelpers.GetCipherIdentityAsync(saveTask.Result.Result.Id, _cipherService);
if (identity != null)
{
await ASCredentialIdentityStore.SharedStore.SaveCredentialIdentitiesAsync(
new ASPasswordCredentialIdentity[] { identity });
}
}
else
{
await ASHelpers.ReplaceAllIdentities(_cipherService);
}
Success();
}
else if(saveTask.Result.Errors.Count() > 0)
{
DisplayAlert(AppResources.AnErrorHasOccurred, saveTask.Result.Errors.First().Message, AppResources.Ok);
}
else
{
DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
}
}
public void DisplayAlert(string title, string message, string accept)
{
var alert = Dialogs.CreateAlert(title, message, accept);
PresentViewController(alert, true, null);
}
private void AlertNoConnection()
{
DisplayAlert(AppResources.InternetConnectionRequiredTitle, AppResources.InternetConnectionRequiredMessage, AppResources.Ok);
}
public class TableSource : UITableViewSource
{
private LoginAddViewController _controller;
public TableSource(LoginAddViewController controller)
{
_controller = controller;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
if(indexPath.Section == 0)
{
if(indexPath.Row == 0)
{
return _controller.NameCell;
}
else if(indexPath.Row == 1)
{
return _controller.UsernameCell;
}
else if(indexPath.Row == 2)
{
return _controller.PasswordCell;
}
else if(indexPath.Row == 3)
{
return _controller.GeneratePasswordCell;
}
}
else if(indexPath.Section == 1)
{
return _controller.UriCell;
}
else if(indexPath.Section == 2)
{
if(indexPath.Row == 0)
{
return _controller.FolderCell;
}
else if(indexPath.Row == 1)
{
return _controller.FavoriteCell;
}
}
else if(indexPath.Section == 3)
{
return _controller.NotesCell;
}
return new UITableViewCell();
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}
public override nint NumberOfSections(UITableView tableView)
{
return 4;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
if(section == 0)
{
return 4;
}
else if(section == 1)
{
return 1;
}
else if(section == 2)
{
return 2;
}
else
{
return 1;
}
}
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
{
return section == 0 || section == 3 ? UITableView.AutomaticDimension : 0.00001f;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
if(section == 0)
{
return AppResources.ItemInformation;
}
else if(section == 3)
{
return AppResources.Notes;
}
return string.Empty;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
tableView.DeselectRow(indexPath, true);
tableView.EndEditing(true);
if(indexPath.Section == 0 && indexPath.Row == 3)
{
_controller.PerformSegue("passwordGeneratorSegue", this);
}
var cell = tableView.CellAt(indexPath);
if(cell == null)
{
return;
}
var selectableCell = cell as ISelectable;
if(selectableCell != null)
{
selectableCell.Select();
}
}
}
}
}

View File

@@ -1,360 +0,0 @@
using System;
using System.Linq;
using Bit.App.Abstractions;
using Bit.iOS.Core.Views;
using Bit.iOS.Core.Models;
using Foundation;
using UIKit;
using XLabs.Ioc;
using Plugin.Settings.Abstractions;
using CoreGraphics;
using Bit.iOS.Core.Utilities;
using Bit.App.Resources;
namespace Bit.iOS.Core.Controllers
{
public abstract class PasswordGeneratorViewController : ExtendedUIViewController
{
private IPasswordGenerationService _passwordGenerationService;
private ISettings _settings;
private bool _isAutofill;
public PasswordGeneratorViewController(IntPtr handle, bool autofill) : base(handle)
{
_isAutofill = autofill;
}
protected IGoogleAnalyticsService GoogleAnalyticsService { get; private set; }
public UITableViewController OptionsTableViewController { get; set; }
public SwitchTableViewCell UppercaseCell { get; set; } = new SwitchTableViewCell("A-Z");
public SwitchTableViewCell LowercaseCell { get; set; } = new SwitchTableViewCell("a-z");
public SwitchTableViewCell NumbersCell { get; set; } = new SwitchTableViewCell("0-9");
public SwitchTableViewCell SpecialCell { get; set; } = new SwitchTableViewCell("!@#$%^&*");
public StepperTableViewCell MinNumbersCell { get; set; } = new StepperTableViewCell(AppResources.MinNumbers, 1, 0, 5, 1);
public StepperTableViewCell MinSpecialCell { get; set; } = new StepperTableViewCell(AppResources.MinSpecial, 1, 0, 5, 1);
public SliderTableViewCell LengthCell { get; set; } = new SliderTableViewCell(AppResources.Length, 10, 5, 64);
public PasswordGenerationOptions PasswordOptions { get; set; }
public abstract UINavigationItem BaseNavItem { get; }
public abstract UIBarButtonItem BaseCancelButton { get; }
public abstract UIBarButtonItem BaseSelectBarButton { get; }
public abstract UILabel BasePasswordLabel { get; }
public override void ViewWillAppear(bool animated)
{
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
base.ViewWillAppear(animated);
}
public override void ViewDidLoad()
{
_passwordGenerationService = Resolver.Resolve<IPasswordGenerationService>();
_settings = Resolver.Resolve<ISettings>();
GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
BaseNavItem.Title = AppResources.PasswordGenerator;
BaseCancelButton.Title = AppResources.Cancel;
BaseSelectBarButton.Title = AppResources.Select;
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
var descriptor = UIFontDescriptor.PreferredBody;
BasePasswordLabel.Font = UIFont.FromName("Menlo-Regular", descriptor.PointSize * 1.3f);
BasePasswordLabel.LineBreakMode = UILineBreakMode.TailTruncation;
BasePasswordLabel.Lines = 1;
BasePasswordLabel.AdjustsFontSizeToFitWidth = false;
var controller = ChildViewControllers.LastOrDefault();
if(controller != null)
{
OptionsTableViewController = controller as UITableViewController;
}
if(OptionsTableViewController != null)
{
OptionsTableViewController.TableView.RowHeight = UITableView.AutomaticDimension;
OptionsTableViewController.TableView.EstimatedRowHeight = 70;
OptionsTableViewController.TableView.Source = new TableSource(this);
OptionsTableViewController.TableView.AllowsSelection = true;
OptionsTableViewController.View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
}
UppercaseCell.Switch.On = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorUppercase, true);
LowercaseCell.Switch.On = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorLowercase, true);
SpecialCell.Switch.On = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorSpecial, true);
NumbersCell.Switch.On = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorNumbers, true);
MinNumbersCell.Value = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorMinNumbers, 1);
MinSpecialCell.Value = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorMinSpecial, 1);
LengthCell.Value = _settings.GetValueOrDefault(App.Constants.PasswordGeneratorLength, 10);
UppercaseCell.ValueChanged += Options_ValueChanged;
LowercaseCell.ValueChanged += Options_ValueChanged;
NumbersCell.ValueChanged += Options_ValueChanged;
SpecialCell.ValueChanged += Options_ValueChanged;
MinNumbersCell.ValueChanged += Options_ValueChanged;
MinSpecialCell.ValueChanged += Options_ValueChanged;
LengthCell.ValueChanged += Options_ValueChanged;
// Adjust based on context password options
if(PasswordOptions != null)
{
if(PasswordOptions.RequireDigits)
{
NumbersCell.Switch.On = true;
NumbersCell.Switch.Enabled = false;
if(MinNumbersCell.Value < 1)
{
MinNumbersCell.Value = 1;
}
MinNumbersCell.Stepper.MinimumValue = 1;
}
if(PasswordOptions.RequireSymbols)
{
SpecialCell.Switch.On = true;
SpecialCell.Switch.Enabled = false;
if(MinSpecialCell.Value < 1)
{
MinSpecialCell.Value = 1;
}
MinSpecialCell.Stepper.MinimumValue = 1;
}
if(PasswordOptions.MinLength < PasswordOptions.MaxLength)
{
if(PasswordOptions.MinLength > 0 && PasswordOptions.MinLength > LengthCell.Slider.MinValue)
{
if(LengthCell.Value < PasswordOptions.MinLength)
{
LengthCell.Slider.Value = PasswordOptions.MinLength;
}
LengthCell.Slider.MinValue = PasswordOptions.MinLength;
}
if(PasswordOptions.MaxLength > 5 && PasswordOptions.MaxLength < LengthCell.Slider.MaxValue)
{
if(LengthCell.Value > PasswordOptions.MaxLength)
{
LengthCell.Slider.Value = PasswordOptions.MaxLength;
}
LengthCell.Slider.MaxValue = PasswordOptions.MaxLength;
}
}
}
GeneratePassword();
if(_isAutofill)
{
GoogleAnalyticsService.TrackAutofillExtensionEvent("GeneratedPassword");
}
else
{
GoogleAnalyticsService.TrackExtensionEvent("GeneratedPassword");
}
base.ViewDidLoad();
}
private void Options_ValueChanged(object sender, EventArgs e)
{
if(InvalidState())
{
LowercaseCell.Switch.On = true;
}
GeneratePassword();
}
private bool InvalidState()
{
return !LowercaseCell.Switch.On && !UppercaseCell.Switch.On && !NumbersCell.Switch.On && !SpecialCell.Switch.On;
}
private void GeneratePassword()
{
BasePasswordLabel.Text = _passwordGenerationService.GeneratePassword(
length: LengthCell.Value,
uppercase: UppercaseCell.Switch.On,
lowercase: LowercaseCell.Switch.On,
numbers: NumbersCell.Switch.On,
special: SpecialCell.Switch.On,
minSpecial: MinSpecialCell.Value,
minNumbers: MinNumbersCell.Value);
}
public class TableSource : UITableViewSource
{
private PasswordGeneratorViewController _controller;
public TableSource(PasswordGeneratorViewController controller)
{
_controller = controller;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
if(indexPath.Section == 0)
{
var cell = new UITableViewCell();
cell.TextLabel.TextColor = new UIColor(red: 0.24f, green: 0.55f, blue: 0.74f, alpha: 1.0f);
if(indexPath.Row == 0)
{
cell.TextLabel.Text = AppResources.RegeneratePassword;
}
else if(indexPath.Row == 1)
{
cell.TextLabel.Text = AppResources.CopyPassword;
}
return cell;
}
if(indexPath.Row == 0)
{
return _controller.LengthCell;
}
else if(indexPath.Row == 1)
{
return _controller.UppercaseCell;
}
else if(indexPath.Row == 2)
{
return _controller.LowercaseCell;
}
else if(indexPath.Row == 3)
{
return _controller.NumbersCell;
}
else if(indexPath.Row == 4)
{
return _controller.SpecialCell;
}
else if(indexPath.Row == 5)
{
return _controller.MinNumbersCell;
}
else if(indexPath.Row == 6)
{
return _controller.MinSpecialCell;
}
return new UITableViewCell();
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}
public override nint NumberOfSections(UITableView tableView)
{
return 2;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
if(section == 0)
{
return 2;
}
return 7;
}
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
{
if(section == 0)
{
return 0.00001f;
}
return UITableView.AutomaticDimension;
}
public override UIView GetViewForHeader(UITableView tableView, nint section)
{
if(section == 0)
{
return new UIView(CGRect.Empty)
{
Hidden = true
};
}
return null;
}
public override string TitleForHeader(UITableView tableView, nint section)
{
if(section == 1)
{
return AppResources.Options;
}
return null;
}
public override string TitleForFooter(UITableView tableView, nint section)
{
if(section == 1)
{
return AppResources.OptionDefaults;
}
return null;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
if(indexPath.Section == 0)
{
if(indexPath.Row == 0)
{
if(_controller._isAutofill)
{
_controller.GoogleAnalyticsService.TrackAutofillExtensionEvent("RegeneratedPassword");
}
else
{
_controller.GoogleAnalyticsService.TrackExtensionEvent("RegeneratedPassword");
}
_controller.GeneratePassword();
}
else if(indexPath.Row == 1)
{
if(_controller._isAutofill)
{
_controller.GoogleAnalyticsService.TrackAutofillExtensionEvent("CopiedGeneratedPassword");
}
else
{
_controller.GoogleAnalyticsService.TrackExtensionEvent("CopiedGeneratedPassword");
}
UIPasteboard clipboard = UIPasteboard.General;
clipboard.String = _controller.BasePasswordLabel.Text;
var alert = Dialogs.CreateMessageAlert(AppResources.Copied);
_controller.PresentViewController(alert, true, () =>
{
_controller.DismissViewController(true, null);
});
}
}
tableView.DeselectRow(indexPath, true);
tableView.EndEditing(true);
}
public NSDate DateTimeToNSDate(DateTime date)
{
DateTime reference = TimeZone.CurrentTimeZone.ToLocalTime(
new DateTime(2001, 1, 1, 0, 0, 0));
return NSDate.FromTimeIntervalSinceReferenceDate(
(date - reference).TotalSeconds);
}
}
}
}