mirror of
https://github.com/bitwarden/android.git
synced 2024-12-18 23:31:52 +03:00
password lock VC for extension
This commit is contained in:
parent
c2cb5ac7c9
commit
047f5b100f
4 changed files with 208 additions and 35 deletions
|
@ -8,13 +8,14 @@ namespace Bit.iOS.Core.Views
|
|||
public FormEntryTableViewCell(
|
||||
string labelName = null,
|
||||
bool useTextView = false,
|
||||
nfloat? height = null)
|
||||
nfloat? height = null,
|
||||
bool useLabelAsPlaceholder = false)
|
||||
: base(UITableViewCellStyle.Default, nameof(FormEntryTableViewCell))
|
||||
{
|
||||
var descriptor = UIFontDescriptor.PreferredBody;
|
||||
var pointSize = descriptor.PointSize;
|
||||
|
||||
if(labelName != null)
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
Label = new UILabel
|
||||
{
|
||||
|
@ -42,7 +43,7 @@ namespace Bit.iOS.Core.Views
|
|||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextView, NSLayoutAttribute.Bottom, 1f, 10f)
|
||||
});
|
||||
|
||||
if(labelName != null)
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
|
||||
|
@ -69,6 +70,11 @@ namespace Bit.iOS.Core.Views
|
|||
ClearButtonMode = UITextFieldViewMode.WhileEditing
|
||||
};
|
||||
|
||||
if(useLabelAsPlaceholder)
|
||||
{
|
||||
TextField.Placeholder = labelName;
|
||||
}
|
||||
|
||||
ContentView.Add(TextField);
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
|
@ -76,7 +82,7 @@ namespace Bit.iOS.Core.Views
|
|||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Bottom, 1f, 10f)
|
||||
});
|
||||
|
||||
if(labelName != null)
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
|
||||
|
@ -94,7 +100,7 @@ namespace Bit.iOS.Core.Views
|
|||
}
|
||||
}
|
||||
|
||||
if(labelName != null)
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(Label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
|
|
|
@ -5,17 +5,27 @@ using XLabs.Ioc;
|
|||
using Plugin.Settings.Abstractions;
|
||||
using Foundation;
|
||||
using MobileCoreServices;
|
||||
using Bit.iOS.Core.Views;
|
||||
using Bit.App.Resources;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.iOS.Core.Utilities;
|
||||
using Bit.App.Abstractions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LockPasswordViewController : UIViewController
|
||||
public partial class LockPasswordViewController : UITableViewController
|
||||
{
|
||||
private ISettings _settings;
|
||||
private IAuthService _authService;
|
||||
private ICryptoService _cryptoService;
|
||||
|
||||
public LockPasswordViewController(IntPtr handle) : base(handle)
|
||||
{ }
|
||||
|
||||
public Context Context { get; set; }
|
||||
public FormEntryTableViewCell MasterPasswordCell { get; set; } = new FormEntryTableViewCell(
|
||||
AppResources.MasterPassword, useLabelAsPlaceholder: true);
|
||||
|
||||
public override void ViewWillAppear(bool animated)
|
||||
{
|
||||
|
@ -27,14 +37,72 @@ namespace Bit.iOS.Extension
|
|||
public override void ViewDidLoad()
|
||||
{
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
_authService = Resolver.Resolve<IAuthService>();
|
||||
_cryptoService = Resolver.Resolve<ICryptoService>();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
partial void SubmitButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
CheckPassword();
|
||||
}
|
||||
|
||||
private 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);
|
||||
if(key.SequenceEqual(_cryptoService.Key))
|
||||
{
|
||||
MasterPasswordCell.TextField.ResignFirstResponder();
|
||||
DismissModalViewController(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: keep track of invalid attempts and logout?
|
||||
|
||||
var alert = Dialogs.CreateAlert(AppResources.AnErrorHasOccurred,
|
||||
string.Format(null, "Invalid Master Password. Try again."), AppResources.Ok, (a) =>
|
||||
{
|
||||
|
||||
MasterPasswordCell.TextField.Text = string.Empty;
|
||||
MasterPasswordCell.TextField.BecomeFirstResponder();
|
||||
});
|
||||
|
||||
PresentViewController(alert, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
partial void CancelButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
CompleteRequest();
|
||||
|
@ -48,5 +116,76 @@ namespace Bit.iOS.Extension
|
|||
|
||||
Context.ExtContext.CompleteRequest(returningItems, 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,38 @@ namespace Bit.iOS.Extension
|
|||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem CancelButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UITableView MainTableView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem SubmitButton { get; set; }
|
||||
|
||||
[Action ("CancelButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void CancelButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
[Action ("SubmitButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void SubmitButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (CancelButton != null) {
|
||||
CancelButton.Dispose ();
|
||||
CancelButton = null;
|
||||
}
|
||||
|
||||
if (MainTableView != null) {
|
||||
MainTableView.Dispose ();
|
||||
MainTableView = null;
|
||||
}
|
||||
|
||||
if (SubmitButton != null) {
|
||||
SubmitButton.Dispose ();
|
||||
SubmitButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -424,34 +424,6 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="1886" y="1931"/>
|
||||
</scene>
|
||||
<scene sceneID="6841">
|
||||
<objects>
|
||||
<viewController id="6842" sceneMemberID="viewController" customClass="LockPasswordViewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="6852"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="6850"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="6845">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<subviews/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Verify Master Password" id="6843">
|
||||
<barButtonItem key="leftBarButtonItem" id="6844" title="Cancel">
|
||||
<connections>
|
||||
<action selector="CancelButton_Activated:" destination="6842" id="7331"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="CancelButton" destination="6844" id="name-outlet-6844"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6853" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2653" y="2664"/>
|
||||
</scene>
|
||||
<scene sceneID="6854">
|
||||
<objects>
|
||||
<navigationController definesPresentationContext="YES" id="6855" sceneMemberID="viewController">
|
||||
|
@ -460,13 +432,47 @@
|
|||
<rect key="frame" x="0.0" y="20" width="600" height="44"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="6842" kind="relationship" relationship="rootViewController" id="6856"/>
|
||||
<segue id="8266" destination="7413" kind="relationship" relationship="rootViewController"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6858" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1878" y="2669"/>
|
||||
</scene>
|
||||
<scene sceneID="7412">
|
||||
<objects>
|
||||
<tableViewController id="7413" sceneMemberID="viewController" customClass="LockPasswordViewController">
|
||||
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="7414">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="7413" id="7415"/>
|
||||
<outlet property="delegate" destination="7413" id="7416"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem title="Verify Master Password" id="8265" key="navigationItem">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="8268">
|
||||
<connections>
|
||||
<action selector="CancelButton_Activated:" destination="7413" id="8287"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" title="Submit" id="8269">
|
||||
<connections>
|
||||
<action selector="SubmitButton_Activated:" destination="7413" id="8288"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="SubmitButton" destination="8269" id="name-outlet-8269"/>
|
||||
<outlet property="CancelButton" destination="8268" id="name-outlet-8268"/>
|
||||
<outlet property="MainTableView" destination="7414" id="name-outlet-7414"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="7419" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2532" y="2675"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="logo.png" width="282" height="44"/>
|
||||
|
|
Loading…
Reference in a new issue