2016-07-13 07:39:24 +03:00
|
|
|
using System;
|
|
|
|
using System.Linq;
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
using Bit.iOS.Core.Views;
|
|
|
|
using Bit.iOS.Extension.Models;
|
|
|
|
using Foundation;
|
|
|
|
using UIKit;
|
|
|
|
using XLabs.Ioc;
|
2016-07-14 07:56:55 +03:00
|
|
|
using Plugin.Settings.Abstractions;
|
2016-07-15 02:01:34 +03:00
|
|
|
using CoreGraphics;
|
2016-07-15 08:01:00 +03:00
|
|
|
using Bit.App;
|
|
|
|
using Bit.iOS.Core.Utilities;
|
2016-08-04 07:06:09 +03:00
|
|
|
using Bit.iOS.Core.Controllers;
|
2016-07-13 07:39:24 +03:00
|
|
|
|
|
|
|
namespace Bit.iOS.Extension
|
|
|
|
{
|
2016-08-04 07:06:09 +03:00
|
|
|
public partial class PasswordGeneratorViewController : ExtendedUIViewController
|
2016-07-13 07:39:24 +03:00
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
private IPasswordGenerationService _passwordGenerationService;
|
|
|
|
private ISettings _settings;
|
2016-08-04 07:25:10 +03:00
|
|
|
private IGoogleAnalyticsService _googleAnalyticsService;
|
2016-07-14 07:56:55 +03:00
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
public PasswordGeneratorViewController(IntPtr handle) : base(handle)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
public Context Context { get; set; }
|
|
|
|
public SiteAddViewController Parent { get; set; }
|
2016-07-14 07:56:55 +03:00
|
|
|
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("!@#$%^&*");
|
2016-07-15 02:01:34 +03:00
|
|
|
public StepperTableViewCell MinNumbersCell { get; set; } = new StepperTableViewCell("Minimum Numbers", 1, 0, 5, 1);
|
|
|
|
public StepperTableViewCell MinSpecialCell { get; set; } = new StepperTableViewCell("Minimum Special", 1, 0, 5, 1);
|
2016-07-15 02:44:04 +03:00
|
|
|
public SliderTableViewCell LengthCell { get; set; } = new SliderTableViewCell("Length", 10, 5, 64);
|
2016-07-13 07:39:24 +03:00
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
_passwordGenerationService = Resolver.Resolve<IPasswordGenerationService>();
|
|
|
|
_settings = Resolver.Resolve<ISettings>();
|
2016-08-04 07:25:10 +03:00
|
|
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
2016-07-14 07:56:55 +03:00
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
|
|
|
|
|
2016-07-15 02:01:34 +03:00
|
|
|
var descriptor = UIFontDescriptor.PreferredBody;
|
|
|
|
PasswordLabel.Font = UIFont.FromName("Courier", descriptor.PointSize * 1.3f);
|
|
|
|
PasswordLabel.LineBreakMode = UILineBreakMode.TailTruncation;
|
|
|
|
PasswordLabel.Lines = 1;
|
|
|
|
PasswordLabel.AdjustsFontSizeToFitWidth = false;
|
2016-07-14 07:56:55 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-07-15 08:01:00 +03:00
|
|
|
UppercaseCell.Switch.On = _settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true);
|
|
|
|
LowercaseCell.Switch.On = _settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true);
|
|
|
|
SpecialCell.Switch.On = _settings.GetValueOrDefault(Constants.PasswordGeneratorSpecial, true);
|
|
|
|
NumbersCell.Switch.On = _settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true);
|
|
|
|
MinNumbersCell.Value = _settings.GetValueOrDefault(Constants.PasswordGeneratorMinNumbers, 1);
|
|
|
|
MinSpecialCell.Value = _settings.GetValueOrDefault(Constants.PasswordGeneratorMinSpecial, 1);
|
|
|
|
LengthCell.Value = _settings.GetValueOrDefault(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(Context.PasswordOptions != null)
|
|
|
|
{
|
|
|
|
if(Context.PasswordOptions.RequireDigits)
|
|
|
|
{
|
|
|
|
NumbersCell.Switch.On = true;
|
|
|
|
NumbersCell.Switch.Enabled = false;
|
|
|
|
|
|
|
|
if(MinNumbersCell.Value < 1)
|
|
|
|
{
|
|
|
|
MinNumbersCell.Value = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
MinNumbersCell.Stepper.MinimumValue = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Context.PasswordOptions.RequireSymbols)
|
|
|
|
{
|
|
|
|
SpecialCell.Switch.On = true;
|
|
|
|
SpecialCell.Switch.Enabled = false;
|
|
|
|
|
|
|
|
if(MinSpecialCell.Value < 1)
|
|
|
|
{
|
|
|
|
MinSpecialCell.Value = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
MinSpecialCell.Stepper.MinimumValue = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Context.PasswordOptions.MinLength < Context.PasswordOptions.MaxLength)
|
|
|
|
{
|
|
|
|
if(Context.PasswordOptions.MinLength > 0 && Context.PasswordOptions.MinLength > LengthCell.Slider.MinValue)
|
|
|
|
{
|
|
|
|
if(LengthCell.Value < Context.PasswordOptions.MinLength)
|
|
|
|
{
|
|
|
|
LengthCell.Slider.Value = Context.PasswordOptions.MinLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
LengthCell.Slider.MinValue = Context.PasswordOptions.MinLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Context.PasswordOptions.MaxLength > 5 && Context.PasswordOptions.MaxLength < LengthCell.Slider.MaxValue)
|
|
|
|
{
|
|
|
|
if(LengthCell.Value > Context.PasswordOptions.MaxLength)
|
|
|
|
{
|
|
|
|
LengthCell.Slider.Value = Context.PasswordOptions.MaxLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
LengthCell.Slider.MaxValue = Context.PasswordOptions.MaxLength;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GeneratePassword();
|
2016-07-13 07:39:24 +03:00
|
|
|
base.ViewDidLoad();
|
|
|
|
}
|
|
|
|
|
2016-07-15 08:01:00 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
partial void SelectBarButton_Activated(UIBarButtonItem sender)
|
|
|
|
{
|
2016-07-15 08:28:12 +03:00
|
|
|
DismissViewController(true, () =>
|
|
|
|
{
|
|
|
|
Parent.PasswordCell.TextField.Text = PasswordLabel.Text;
|
|
|
|
});
|
2016-07-13 07:39:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
partial void CancelBarButton_Activated(UIBarButtonItem sender)
|
|
|
|
{
|
2016-07-15 08:28:12 +03:00
|
|
|
DismissViewController(true, null);
|
2016-07-13 07:39:24 +03:00
|
|
|
}
|
|
|
|
|
2016-07-15 08:01:00 +03:00
|
|
|
private void GeneratePassword()
|
|
|
|
{
|
2016-08-04 07:25:10 +03:00
|
|
|
_googleAnalyticsService.TrackExtensionEvent("GeneratePassword");
|
2016-07-15 08:01:00 +03:00
|
|
|
PasswordLabel.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);
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
public class TableSource : UITableViewSource
|
|
|
|
{
|
|
|
|
private PasswordGeneratorViewController _controller;
|
|
|
|
|
|
|
|
public TableSource(PasswordGeneratorViewController controller)
|
|
|
|
{
|
|
|
|
_controller = controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
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 = "Regenerate Password";
|
|
|
|
}
|
|
|
|
else if(indexPath.Row == 1)
|
|
|
|
{
|
|
|
|
cell.TextLabel.Text = "Copy Password";
|
|
|
|
}
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(indexPath.Row == 0)
|
|
|
|
{
|
2016-07-15 02:44:04 +03:00
|
|
|
return _controller.LengthCell;
|
2016-07-14 07:56:55 +03:00
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
2016-07-15 02:01:34 +03:00
|
|
|
return _controller.MinNumbersCell;
|
2016-07-14 07:56:55 +03:00
|
|
|
}
|
|
|
|
else if(indexPath.Row == 6)
|
|
|
|
{
|
2016-07-15 02:01:34 +03:00
|
|
|
return _controller.MinSpecialCell;
|
2016-07-14 07:56:55 +03:00
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
return new UITableViewCell();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
|
|
|
|
{
|
|
|
|
return UITableView.AutomaticDimension;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override nint NumberOfSections(UITableView tableView)
|
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
return 2;
|
2016-07-13 07:39:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public override nint RowsInSection(UITableView tableview, nint section)
|
|
|
|
{
|
|
|
|
if(section == 0)
|
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
2016-07-14 07:56:55 +03:00
|
|
|
|
|
|
|
return 7;
|
2016-07-13 07:39:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
|
|
|
|
{
|
2016-07-15 02:01:34 +03:00
|
|
|
if(section == 0)
|
|
|
|
{
|
|
|
|
return 0.00001f;
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
return UITableView.AutomaticDimension;
|
|
|
|
}
|
|
|
|
|
2016-07-15 02:01:34 +03:00
|
|
|
public override UIView GetViewForHeader(UITableView tableView, nint section)
|
|
|
|
{
|
|
|
|
if(section == 0)
|
|
|
|
{
|
|
|
|
return new UIView(CGRect.Empty)
|
|
|
|
{
|
|
|
|
Hidden = true
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
public override string TitleForHeader(UITableView tableView, nint section)
|
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
if(section == 1)
|
|
|
|
{
|
|
|
|
return "Options";
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-07-15 08:01:00 +03:00
|
|
|
public override string TitleForFooter(UITableView tableView, nint section)
|
|
|
|
{
|
|
|
|
if(section == 1)
|
|
|
|
{
|
|
|
|
return "Option defaults are set from the main bitwarden app's password generator tool.";
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
|
|
|
|
{
|
2016-07-14 07:56:55 +03:00
|
|
|
if(indexPath.Section == 0)
|
|
|
|
{
|
|
|
|
if(indexPath.Row == 0)
|
|
|
|
{
|
2016-07-15 08:01:00 +03:00
|
|
|
_controller.GeneratePassword();
|
2016-07-14 07:56:55 +03:00
|
|
|
}
|
|
|
|
else if(indexPath.Row == 1)
|
|
|
|
{
|
2016-07-15 08:01:00 +03:00
|
|
|
UIPasteboard clipboard = UIPasteboard.General;
|
|
|
|
clipboard.String = _controller.PasswordLabel.Text;
|
|
|
|
var alert = Dialogs.CreateMessageAlert("Copied!");
|
|
|
|
_controller.PresentViewController(alert, true, () =>
|
|
|
|
{
|
|
|
|
_controller.DismissViewController(true, null);
|
|
|
|
});
|
2016-07-14 07:56:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:39:24 +03:00
|
|
|
tableView.DeselectRow(indexPath, true);
|
|
|
|
tableView.EndEditing(true);
|
|
|
|
}
|
2016-07-15 08:01:00 +03:00
|
|
|
|
|
|
|
public NSDate DateTimeToNSDate(DateTime date)
|
|
|
|
{
|
|
|
|
DateTime reference = TimeZone.CurrentTimeZone.ToLocalTime(
|
|
|
|
new DateTime(2001, 1, 1, 0, 0, 0));
|
|
|
|
return NSDate.FromTimeIntervalSinceReferenceDate(
|
|
|
|
(date - reference).TotalSeconds);
|
|
|
|
}
|
2016-07-13 07:39:24 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|