mirror of
https://github.com/bitwarden/mobile
synced 2025-12-18 17:23:18 +00:00
add shared controllers and view to ios core
This commit is contained in:
12
src/iOS.Core/Controllers/ExtendedUITableViewController.cs
Normal file
12
src/iOS.Core/Controllers/ExtendedUITableViewController.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Controllers
|
||||
{
|
||||
public class ExtendedUITableViewController : UITableViewController
|
||||
{
|
||||
public ExtendedUITableViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
12
src/iOS.Core/Controllers/ExtendedUIViewController.cs
Normal file
12
src/iOS.Core/Controllers/ExtendedUIViewController.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Controllers
|
||||
{
|
||||
public class ExtendedUIViewController : UIViewController
|
||||
{
|
||||
public ExtendedUIViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
177
src/iOS.Core/Controllers/LockPasswordViewController.cs
Normal file
177
src/iOS.Core/Controllers/LockPasswordViewController.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
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 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()
|
||||
{
|
||||
// _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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
335
src/iOS.Core/Controllers/LoginAddViewController.cs
Normal file
335
src/iOS.Core/Controllers/LoginAddViewController.cs
Normal file
@@ -0,0 +1,335 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bit.App.Resources;
|
||||
using Bit.iOS.Core.Views;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using Bit.iOS.Core.Utilities;
|
||||
using Bit.iOS.Core.Models;
|
||||
using System.Threading.Tasks;
|
||||
using AuthenticationServices;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Exceptions;
|
||||
|
||||
namespace Bit.iOS.Core.Controllers
|
||||
{
|
||||
public abstract class LoginAddViewController : ExtendedUITableViewController
|
||||
{
|
||||
private ICipherService _cipherService;
|
||||
private IFolderService _folderService;
|
||||
private IEnumerable<FolderView> _folders;
|
||||
|
||||
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 = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
_folderService = ServiceContainer.Resolve<IFolderService>("folderService");
|
||||
|
||||
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.GetAllDecryptedAsync().GetAwaiter().GetResult();
|
||||
var folderNames = _folders.Select(s => s.Name).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 CipherView
|
||||
{
|
||||
Name = string.IsNullOrWhiteSpace(NameCell.TextField.Text) ? null : NameCell.TextField.Text,
|
||||
Notes = string.IsNullOrWhiteSpace(NotesCell.TextView.Text) ? null : NotesCell.TextView.Text,
|
||||
Favorite = FavoriteCell.Switch.On,
|
||||
FolderId = FolderCell.SelectedIndex == 0 ? null : _folders.ElementAtOrDefault(FolderCell.SelectedIndex - 1)?.Id,
|
||||
Type = Bit.Core.Enums.CipherType.Login,
|
||||
Login = new LoginView
|
||||
{
|
||||
Uris = null,
|
||||
Username = string.IsNullOrWhiteSpace(UsernameCell.TextField.Text) ? null : UsernameCell.TextField.Text,
|
||||
Password = string.IsNullOrWhiteSpace(PasswordCell.TextField.Text) ? null : PasswordCell.TextField.Text,
|
||||
}
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(UriCell.TextField.Text))
|
||||
{
|
||||
cipher.Login.Uris = new List<LoginUriView>
|
||||
{
|
||||
new LoginUriView
|
||||
{
|
||||
Uri = UriCell.TextField.Text
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var loadingAlert = Dialogs.CreateLoadingAlert(AppResources.Saving);
|
||||
PresentViewController(loadingAlert, true, null);
|
||||
try
|
||||
{
|
||||
var cipherDomain = await _cipherService.EncryptAsync(cipher);
|
||||
await _cipherService.SaveWithServerAsync(cipherDomain);
|
||||
await loadingAlert.DismissViewControllerAsync(true);
|
||||
if(await ASHelpers.IdentitiesCanIncremental())
|
||||
{
|
||||
var identity = await ASHelpers.GetCipherIdentityAsync(cipherDomain.Id, _cipherService);
|
||||
if(identity != null)
|
||||
{
|
||||
await ASCredentialIdentityStore.SharedStore.SaveCredentialIdentitiesAsync(
|
||||
new ASPasswordCredentialIdentity[] { identity });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentities(_cipherService);
|
||||
}
|
||||
Success();
|
||||
}
|
||||
catch(ApiException e)
|
||||
{
|
||||
DisplayAlert(AppResources.AnErrorHasOccurred, e.Error.GetSingleMessage(), 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
335
src/iOS.Core/Controllers/PasswordGeneratorViewController.cs
Normal file
335
src/iOS.Core/Controllers/PasswordGeneratorViewController.cs
Normal file
@@ -0,0 +1,335 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Bit.iOS.Core.Views;
|
||||
using Bit.iOS.Core.Models;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using CoreGraphics;
|
||||
using Bit.iOS.Core.Utilities;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.iOS.Core.Controllers
|
||||
{
|
||||
public abstract class PasswordGeneratorViewController : ExtendedUIViewController
|
||||
{
|
||||
private IPasswordGenerationService _passwordGenerationService;
|
||||
|
||||
public PasswordGeneratorViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
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 async override void ViewDidLoad()
|
||||
{
|
||||
_passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>(
|
||||
"passwordGenerationService");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var options = await _passwordGenerationService.GetOptionsAsync();
|
||||
UppercaseCell.Switch.On = options.Uppercase.GetValueOrDefault();
|
||||
LowercaseCell.Switch.On = options.Lowercase.GetValueOrDefault(true);
|
||||
SpecialCell.Switch.On = options.Special.GetValueOrDefault();
|
||||
NumbersCell.Switch.On = options.Number.GetValueOrDefault();
|
||||
MinNumbersCell.Value = options.MinNumber.GetValueOrDefault(1);
|
||||
MinSpecialCell.Value = options.MinSpecial.GetValueOrDefault(1);
|
||||
LengthCell.Value = options.Length.GetValueOrDefault(14);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var task = GeneratePasswordAsync();
|
||||
base.ViewDidLoad();
|
||||
}
|
||||
|
||||
private void Options_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if(InvalidState())
|
||||
{
|
||||
LowercaseCell.Switch.On = true;
|
||||
}
|
||||
var task = GeneratePasswordAsync();
|
||||
}
|
||||
|
||||
private bool InvalidState()
|
||||
{
|
||||
return !LowercaseCell.Switch.On && !UppercaseCell.Switch.On && !NumbersCell.Switch.On && !SpecialCell.Switch.On;
|
||||
}
|
||||
|
||||
private async Task GeneratePasswordAsync()
|
||||
{
|
||||
BasePasswordLabel.Text = await _passwordGenerationService.GeneratePasswordAsync(
|
||||
new Bit.Core.Models.Domain.PasswordGenerationOptions
|
||||
{
|
||||
Length = LengthCell.Value,
|
||||
Uppercase = UppercaseCell.Switch.On,
|
||||
Lowercase = LowercaseCell.Switch.On,
|
||||
Number = NumbersCell.Switch.On,
|
||||
Special = SpecialCell.Switch.On,
|
||||
MinSpecial = MinSpecialCell.Value,
|
||||
MinNumber = 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)
|
||||
{
|
||||
var task = _controller.GeneratePasswordAsync();
|
||||
}
|
||||
else if(indexPath.Row == 1)
|
||||
{
|
||||
UIPasteboard clipboard = UIPasteboard.General;
|
||||
clipboard.String = _controller.BasePasswordLabel.Text;
|
||||
var alert = Dialogs.CreateMessageAlert(
|
||||
string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user