mirror of
https://github.com/bitwarden/android.git
synced 2025-01-12 11:17:30 +03:00
app extension for autofill ios
This commit is contained in:
parent
f237fa98d2
commit
7a230ee5f5
15 changed files with 1580 additions and 56 deletions
|
@ -122,29 +122,23 @@ namespace Bit.iOS.Autofill
|
|||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
var navController = segue.DestinationViewController as UINavigationController;
|
||||
if(navController != null)
|
||||
if(segue.DestinationViewController is UINavigationController navController)
|
||||
{
|
||||
var listLoginController = navController.TopViewController as LoginListViewController;
|
||||
var listSearchController = navController.TopViewController as LoginSearchViewController;
|
||||
var passwordViewController = navController.TopViewController as LockPasswordViewController;
|
||||
var setupViewController = navController.TopViewController as SetupViewController;
|
||||
|
||||
if(listLoginController != null)
|
||||
if(navController.TopViewController is LoginListViewController listLoginController)
|
||||
{
|
||||
listLoginController.Context = _context;
|
||||
listLoginController.CPViewController = this;
|
||||
}
|
||||
else if(listSearchController != null)
|
||||
else if(navController.TopViewController is LoginSearchViewController listSearchController)
|
||||
{
|
||||
listSearchController.Context = _context;
|
||||
listSearchController.CPViewController = this;
|
||||
}
|
||||
else if(passwordViewController != null)
|
||||
else if(navController.TopViewController is LockPasswordViewController passwordViewController)
|
||||
{
|
||||
passwordViewController.CPViewController = this;
|
||||
}
|
||||
else if(setupViewController != null)
|
||||
else if(navController.TopViewController is SetupViewController setupViewController)
|
||||
{
|
||||
setupViewController.CPViewController = this;
|
||||
}
|
||||
|
|
398
src/iOS.Extension/LoadingViewController.cs
Normal file
398
src/iOS.Extension/LoadingViewController.cs
Normal file
|
@ -0,0 +1,398 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using Bit.iOS.Core;
|
||||
using Newtonsoft.Json;
|
||||
using Bit.iOS.Extension.Models;
|
||||
using MobileCoreServices;
|
||||
using Bit.iOS.Core.Utilities;
|
||||
using Bit.App.Resources;
|
||||
using Bit.iOS.Core.Controllers;
|
||||
using System.Collections.Generic;
|
||||
using Bit.iOS.Core.Models;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LoadingViewController : ExtendedUIViewController
|
||||
{
|
||||
private Context _context = new Context();
|
||||
private readonly JsonSerializerSettings _jsonSettings =
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
|
||||
|
||||
public LoadingViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
InitApp();
|
||||
base.ViewDidLoad();
|
||||
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
|
||||
_context.ExtContext = ExtensionContext;
|
||||
foreach(var item in ExtensionContext.InputItems)
|
||||
{
|
||||
var processed = false;
|
||||
foreach(var itemProvider in item.Attachments)
|
||||
{
|
||||
if(ProcessWebUrlProvider(itemProvider)
|
||||
|| ProcessFindLoginProvider(itemProvider)
|
||||
|| ProcessFindLoginBrowserProvider(itemProvider, Constants.UTTypeAppExtensionFillBrowserAction)
|
||||
|| ProcessFindLoginBrowserProvider(itemProvider, Constants.UTTypeAppExtensionFillWebViewAction)
|
||||
|| ProcessSaveLoginProvider(itemProvider)
|
||||
|| ProcessChangePasswordProvider(itemProvider)
|
||||
|| ProcessExtensionSetupProvider(itemProvider))
|
||||
{
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(processed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
if(!IsAuthed())
|
||||
{
|
||||
var alert = Dialogs.CreateAlert(null, AppResources.MustLogInMainApp, AppResources.Ok, (a) =>
|
||||
{
|
||||
CompleteRequest(null);
|
||||
});
|
||||
PresentViewController(alert, true, null);
|
||||
return;
|
||||
}
|
||||
if(_context.ProviderType == Constants.UTTypeAppExtensionSetup)
|
||||
{
|
||||
PerformSegue("setupSegue", this);
|
||||
return;
|
||||
}
|
||||
if(IsLocked())
|
||||
{
|
||||
PerformSegue("lockPasswordSegue", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContinueOn();
|
||||
}
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if(segue.DestinationViewController is UINavigationController navController)
|
||||
{
|
||||
if(navController.TopViewController is LoginListViewController listLoginController)
|
||||
{
|
||||
listLoginController.Context = _context;
|
||||
listLoginController.LoadingController = this;
|
||||
}
|
||||
else if(navController.TopViewController is LoginAddViewController addLoginController)
|
||||
{
|
||||
addLoginController.Context = _context;
|
||||
addLoginController.LoadingController = this;
|
||||
}
|
||||
else if(navController.TopViewController is LockPasswordViewController passwordViewController)
|
||||
{
|
||||
passwordViewController.LoadingController = this;
|
||||
}
|
||||
else if(navController.TopViewController is SetupViewController setupViewController)
|
||||
{
|
||||
setupViewController.Context = _context;
|
||||
setupViewController.LoadingController = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DismissLockAndContinue()
|
||||
{
|
||||
Debug.WriteLine("BW Log, Dismissing lock controller.");
|
||||
DismissViewController(false, () => ContinueOn());
|
||||
}
|
||||
|
||||
private void ContinueOn()
|
||||
{
|
||||
Debug.WriteLine("BW Log, Segue to setup, login add or list.");
|
||||
if(_context.ProviderType == Constants.UTTypeAppExtensionSaveLoginAction)
|
||||
{
|
||||
PerformSegue("newLoginSegue", this);
|
||||
}
|
||||
else if(_context.ProviderType == Constants.UTTypeAppExtensionSetup)
|
||||
{
|
||||
PerformSegue("setupSegue", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
PerformSegue("loginListSegue", this);
|
||||
}
|
||||
}
|
||||
|
||||
public void CompleteUsernamePasswordRequest(string username, string password,
|
||||
List<Tuple<string, string>> fields, string totp)
|
||||
{
|
||||
NSDictionary itemData = null;
|
||||
if(_context.ProviderType == UTType.PropertyList)
|
||||
{
|
||||
var fillScript = new FillScript(_context.Details, username, password, fields);
|
||||
var scriptJson = JsonConvert.SerializeObject(fillScript, _jsonSettings);
|
||||
var scriptDict = new NSDictionary(Constants.AppExtensionWebViewPageFillScript, scriptJson);
|
||||
itemData = new NSDictionary(NSJavaScriptExtension.FinalizeArgumentKey, scriptDict);
|
||||
}
|
||||
else if(_context.ProviderType == Constants.UTTypeAppExtensionFindLoginAction)
|
||||
{
|
||||
itemData = new NSDictionary(
|
||||
Constants.AppExtensionUsernameKey, username,
|
||||
Constants.AppExtensionPasswordKey, password);
|
||||
}
|
||||
else if(_context.ProviderType == Constants.UTTypeAppExtensionFillBrowserAction
|
||||
|| _context.ProviderType == Constants.UTTypeAppExtensionFillWebViewAction)
|
||||
{
|
||||
var fillScript = new FillScript(_context.Details, username, password, fields);
|
||||
var scriptJson = JsonConvert.SerializeObject(fillScript, _jsonSettings);
|
||||
itemData = new NSDictionary(Constants.AppExtensionWebViewPageFillScript, scriptJson);
|
||||
}
|
||||
else if(_context.ProviderType == Constants.UTTypeAppExtensionSaveLoginAction)
|
||||
{
|
||||
itemData = new NSDictionary(
|
||||
Constants.AppExtensionUsernameKey, username,
|
||||
Constants.AppExtensionPasswordKey, password);
|
||||
}
|
||||
else if(_context.ProviderType == Constants.UTTypeAppExtensionChangePasswordAction)
|
||||
{
|
||||
itemData = new NSDictionary(
|
||||
Constants.AppExtensionPasswordKey, string.Empty,
|
||||
Constants.AppExtensionOldPasswordKey, password);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(totp))
|
||||
{
|
||||
UIPasteboard.General.String = totp;
|
||||
}
|
||||
CompleteRequest(itemData);
|
||||
}
|
||||
|
||||
public void CompleteRequest(NSDictionary itemData)
|
||||
{
|
||||
Debug.WriteLine("BW LOG, itemData: " + itemData);
|
||||
var resultsProvider = new NSItemProvider(itemData, UTType.PropertyList);
|
||||
var resultsItem = new NSExtensionItem { Attachments = new NSItemProvider[] { resultsProvider } };
|
||||
var returningItems = new NSExtensionItem[] { resultsItem };
|
||||
NSRunLoop.Main.BeginInvokeOnMainThread(() => ExtensionContext?.CompleteRequest(returningItems, null));
|
||||
}
|
||||
|
||||
private bool ProcessItemProvider(NSItemProvider itemProvider, string type, Action<NSDictionary> dictAction,
|
||||
Action<NSUrl> urlAction = null)
|
||||
{
|
||||
if(!itemProvider.HasItemConformingTo(type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
itemProvider.LoadItem(type, null, (NSObject list, NSError error) =>
|
||||
{
|
||||
if(list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_context.ProviderType = type;
|
||||
if(list is NSDictionary dict && dictAction != null)
|
||||
{
|
||||
dictAction(dict);
|
||||
}
|
||||
else if(list is NSUrl && urlAction != null)
|
||||
{
|
||||
var url = list as NSUrl;
|
||||
urlAction(url);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Cannot parse list for action. List is " +
|
||||
(list?.GetType().ToString() ?? "null"));
|
||||
}
|
||||
|
||||
Debug.WriteLine("BW LOG, ProviderType: " + _context.ProviderType);
|
||||
Debug.WriteLine("BW LOG, Url: " + _context.UrlString);
|
||||
Debug.WriteLine("BW LOG, Title: " + _context.LoginTitle);
|
||||
Debug.WriteLine("BW LOG, Username: " + _context.Username);
|
||||
Debug.WriteLine("BW LOG, Password: " + _context.Password);
|
||||
Debug.WriteLine("BW LOG, Old Password: " + _context.OldPassword);
|
||||
Debug.WriteLine("BW LOG, Notes: " + _context.Notes);
|
||||
Debug.WriteLine("BW LOG, Details: " + _context.Details);
|
||||
|
||||
if(_context.PasswordOptions != null)
|
||||
{
|
||||
Debug.WriteLine("BW LOG, PasswordOptions Min Length: " + _context.PasswordOptions.MinLength);
|
||||
Debug.WriteLine("BW LOG, PasswordOptions Max Length: " + _context.PasswordOptions.MaxLength);
|
||||
Debug.WriteLine("BW LOG, PasswordOptions Require Digits: " + _context.PasswordOptions.RequireDigits);
|
||||
Debug.WriteLine("BW LOG, PasswordOptions Require Symbols: " + _context.PasswordOptions.RequireSymbols);
|
||||
Debug.WriteLine("BW LOG, PasswordOptions Forbidden Chars: " + _context.PasswordOptions.ForbiddenCharacters);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessWebUrlProvider(NSItemProvider itemProvider)
|
||||
{
|
||||
return ProcessItemProvider(itemProvider, UTType.PropertyList, dict =>
|
||||
{
|
||||
var result = dict[NSJavaScriptExtension.PreprocessingResultsKey];
|
||||
if(result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_context.UrlString = result.ValueForKey(new NSString(Constants.AppExtensionUrlStringKey)) as NSString;
|
||||
var jsonStr = result.ValueForKey(new NSString(Constants.AppExtensionWebViewPageDetails)) as NSString;
|
||||
_context.Details = DeserializeString<PageDetails>(jsonStr);
|
||||
});
|
||||
}
|
||||
|
||||
private bool ProcessFindLoginProvider(NSItemProvider itemProvider)
|
||||
{
|
||||
return ProcessItemProvider(itemProvider, Constants.UTTypeAppExtensionFindLoginAction, dict =>
|
||||
{
|
||||
var version = dict[Constants.AppExtensionVersionNumberKey] as NSNumber;
|
||||
var url = dict[Constants.AppExtensionUrlStringKey] as NSString;
|
||||
if(url != null)
|
||||
{
|
||||
_context.UrlString = url;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private bool ProcessFindLoginBrowserProvider(NSItemProvider itemProvider, string action)
|
||||
{
|
||||
return ProcessItemProvider(itemProvider, action, dict =>
|
||||
{
|
||||
var version = dict[Constants.AppExtensionVersionNumberKey] as NSNumber;
|
||||
var url = dict[Constants.AppExtensionUrlStringKey] as NSString;
|
||||
if(url != null)
|
||||
{
|
||||
_context.UrlString = url;
|
||||
}
|
||||
_context.Details = DeserializeDictionary<PageDetails>(dict[Constants.AppExtensionWebViewPageDetails] as NSDictionary);
|
||||
}, url =>
|
||||
{
|
||||
if(url != null)
|
||||
{
|
||||
_context.UrlString = url.AbsoluteString;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private bool ProcessSaveLoginProvider(NSItemProvider itemProvider)
|
||||
{
|
||||
return ProcessItemProvider(itemProvider, Constants.UTTypeAppExtensionSaveLoginAction, dict =>
|
||||
{
|
||||
var version = dict[Constants.AppExtensionVersionNumberKey] as NSNumber;
|
||||
var url = dict[Constants.AppExtensionUrlStringKey] as NSString;
|
||||
var title = dict[Constants.AppExtensionTitleKey] as NSString;
|
||||
var sectionTitle = dict[Constants.AppExtensionSectionTitleKey] as NSString;
|
||||
var username = dict[Constants.AppExtensionUsernameKey] as NSString;
|
||||
var password = dict[Constants.AppExtensionPasswordKey] as NSString;
|
||||
var notes = dict[Constants.AppExtensionNotesKey] as NSString;
|
||||
var fields = dict[Constants.AppExtensionFieldsKey] as NSDictionary;
|
||||
if(url != null)
|
||||
{
|
||||
_context.UrlString = url;
|
||||
}
|
||||
_context.LoginTitle = title;
|
||||
_context.Username = username;
|
||||
_context.Password = password;
|
||||
_context.Notes = notes;
|
||||
_context.PasswordOptions = DeserializeDictionary<PasswordGenerationOptions>(dict[Constants.AppExtensionPasswordGeneratorOptionsKey] as NSDictionary);
|
||||
});
|
||||
}
|
||||
|
||||
private bool ProcessChangePasswordProvider(NSItemProvider itemProvider)
|
||||
{
|
||||
return ProcessItemProvider(itemProvider, Constants.UTTypeAppExtensionChangePasswordAction, dict =>
|
||||
{
|
||||
var version = dict[Constants.AppExtensionVersionNumberKey] as NSNumber;
|
||||
var url = dict[Constants.AppExtensionUrlStringKey] as NSString;
|
||||
var title = dict[Constants.AppExtensionTitleKey] as NSString;
|
||||
var sectionTitle = dict[Constants.AppExtensionSectionTitleKey] as NSString;
|
||||
var username = dict[Constants.AppExtensionUsernameKey] as NSString;
|
||||
var password = dict[Constants.AppExtensionPasswordKey] as NSString;
|
||||
var oldPassword = dict[Constants.AppExtensionOldPasswordKey] as NSString;
|
||||
var notes = dict[Constants.AppExtensionNotesKey] as NSString;
|
||||
var fields = dict[Constants.AppExtensionFieldsKey] as NSDictionary;
|
||||
if(url != null)
|
||||
{
|
||||
_context.UrlString = url;
|
||||
}
|
||||
_context.LoginTitle = title;
|
||||
_context.Username = username;
|
||||
_context.Password = password;
|
||||
_context.OldPassword = oldPassword;
|
||||
_context.Notes = notes;
|
||||
_context.PasswordOptions = DeserializeDictionary<PasswordGenerationOptions>(dict[Constants.AppExtensionPasswordGeneratorOptionsKey] as NSDictionary);
|
||||
});
|
||||
}
|
||||
|
||||
private bool ProcessExtensionSetupProvider(NSItemProvider itemProvider)
|
||||
{
|
||||
if(itemProvider.HasItemConformingTo(Constants.UTTypeAppExtensionSetup))
|
||||
{
|
||||
_context.ProviderType = Constants.UTTypeAppExtensionSetup;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private T DeserializeDictionary<T>(NSDictionary dict)
|
||||
{
|
||||
if(dict != null)
|
||||
{
|
||||
var jsonData = NSJsonSerialization.Serialize(
|
||||
dict, NSJsonWritingOptions.PrettyPrinted, out NSError jsonError);
|
||||
if(jsonData != null)
|
||||
{
|
||||
var jsonString = new NSString(jsonData, NSStringEncoding.UTF8);
|
||||
return DeserializeString<T>(jsonString);
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
private T DeserializeString<T>(NSString jsonString)
|
||||
{
|
||||
if(jsonString != null)
|
||||
{
|
||||
var convertedObject = JsonConvert.DeserializeObject<T>(jsonString.ToString());
|
||||
return convertedObject;
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
private void InitApp()
|
||||
{
|
||||
if(ServiceContainer.RegisteredServices.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
iOSCoreHelpers.RegisterLocalServices();
|
||||
ServiceContainer.Init();
|
||||
iOSCoreHelpers.RegisterHockeyApp();
|
||||
iOSCoreHelpers.Bootstrap();
|
||||
}
|
||||
|
||||
private bool IsLocked()
|
||||
{
|
||||
var lockService = ServiceContainer.Resolve<ILockService>("lockService");
|
||||
return lockService.IsLockedAsync().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private bool IsAuthed()
|
||||
{
|
||||
var userService = ServiceContainer.Resolve<IUserService>("userService");
|
||||
return userService.IsAuthenticatedAsync().GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
}
|
21
src/iOS.Extension/LoadingViewController.designer.cs
generated
Normal file
21
src/iOS.Extension/LoadingViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,21 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("LoadingViewController")]
|
||||
partial class LoadingViewController
|
||||
{
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
28
src/iOS.Extension/LockPasswordViewController.cs
Normal file
28
src/iOS.Extension/LockPasswordViewController.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LockPasswordViewController : Core.Controllers.LockPasswordViewController
|
||||
{
|
||||
public LockPasswordViewController(IntPtr handle) : base(handle)
|
||||
{ }
|
||||
|
||||
public LoadingViewController LoadingController { get; set; }
|
||||
public override UINavigationItem BaseNavItem => NavItem;
|
||||
public override UIBarButtonItem BaseCancelButton => CancelButton;
|
||||
public override UIBarButtonItem BaseSubmitButton => SubmitButton;
|
||||
public override Action Success => () => LoadingController.DismissLockAndContinue();
|
||||
public override Action Cancel => () => LoadingController.CompleteRequest(null);
|
||||
|
||||
partial void SubmitButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
var task = CheckPasswordAsync();
|
||||
}
|
||||
|
||||
partial void CancelButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
}
|
||||
}
|
64
src/iOS.Extension/LockPasswordViewController.designer.cs
generated
Normal file
64
src/iOS.Extension/LockPasswordViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,64 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("LockPasswordViewController")]
|
||||
partial class LockPasswordViewController
|
||||
{
|
||||
[Outlet]
|
||||
[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.UINavigationItem NavItem { 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 (NavItem != null) {
|
||||
NavItem.Dispose ();
|
||||
NavItem = null;
|
||||
}
|
||||
|
||||
if (SubmitButton != null) {
|
||||
SubmitButton.Dispose ();
|
||||
SubmitButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
src/iOS.Extension/LoginAddViewController.cs
Normal file
62
src/iOS.Extension/LoginAddViewController.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LoginAddViewController : Core.Controllers.LoginAddViewController
|
||||
{
|
||||
public LoginAddViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
public LoginListViewController LoginListController { get; set; }
|
||||
public LoadingViewController LoadingController { get; set; }
|
||||
|
||||
public override UINavigationItem BaseNavItem => NavItem;
|
||||
public override UIBarButtonItem BaseCancelButton => CancelBarButton;
|
||||
public override UIBarButtonItem BaseSaveButton => SaveBarButton;
|
||||
|
||||
public override Action Success => () =>
|
||||
{
|
||||
if(LoginListController != null)
|
||||
{
|
||||
LoginListController.DismissModal();
|
||||
}
|
||||
else if(LoadingController != null)
|
||||
{
|
||||
LoadingController.CompleteUsernamePasswordRequest(UsernameCell.TextField.Text,
|
||||
PasswordCell.TextField.Text, null, null);
|
||||
}
|
||||
};
|
||||
|
||||
partial void CancelBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
if(LoginListController != null)
|
||||
{
|
||||
DismissViewController(true, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadingController.CompleteRequest(null);
|
||||
}
|
||||
}
|
||||
|
||||
async partial void SaveBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
await this.SaveAsync();
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if(segue.DestinationViewController is UINavigationController navController)
|
||||
{
|
||||
if(navController.TopViewController is PasswordGeneratorViewController passwordGeneratorController)
|
||||
{
|
||||
passwordGeneratorController.PasswordOptions = Context.PasswordOptions;
|
||||
passwordGeneratorController.Parent = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
src/iOS.Extension/LoginAddViewController.designer.cs
generated
Normal file
55
src/iOS.Extension/LoginAddViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,55 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("LoginAddViewController")]
|
||||
partial class LoginAddViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem CancelBarButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UINavigationItem NavItem { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem SaveBarButton { get; set; }
|
||||
|
||||
[Action ("CancelBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void CancelBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
[Action ("SaveBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void SaveBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (CancelBarButton != null) {
|
||||
CancelBarButton.Dispose ();
|
||||
CancelBarButton = null;
|
||||
}
|
||||
|
||||
if (NavItem != null) {
|
||||
NavItem.Dispose ();
|
||||
NavItem = null;
|
||||
}
|
||||
|
||||
if (SaveBarButton != null) {
|
||||
SaveBarButton.Dispose ();
|
||||
SaveBarButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
197
src/iOS.Extension/LoginListViewController.cs
Normal file
197
src/iOS.Extension/LoginListViewController.cs
Normal file
|
@ -0,0 +1,197 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Bit.iOS.Extension.Models;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using Bit.iOS.Core.Utilities;
|
||||
using Bit.iOS.Core;
|
||||
using MobileCoreServices;
|
||||
using Bit.iOS.Core.Controllers;
|
||||
using Bit.App.Resources;
|
||||
using Bit.iOS.Core.Views;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class LoginListViewController : ExtendedUITableViewController
|
||||
{
|
||||
public LoginListViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
public Context Context { get; set; }
|
||||
public LoadingViewController LoadingController { get; set; }
|
||||
|
||||
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()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
NavItem.Title = AppResources.Items;
|
||||
if(!CanAutoFill())
|
||||
{
|
||||
CancelBarButton.Title = AppResources.Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
CancelBarButton.Title = AppResources.Cancel;
|
||||
}
|
||||
TableView.RowHeight = UITableView.AutomaticDimension;
|
||||
TableView.EstimatedRowHeight = 44;
|
||||
TableView.Source = new TableSource(this);
|
||||
await ((TableSource)TableView.Source).LoadItemsAsync();
|
||||
}
|
||||
|
||||
public bool CanAutoFill()
|
||||
{
|
||||
if(Context.ProviderType != Constants.UTTypeAppExtensionFillBrowserAction
|
||||
&& Context.ProviderType != Constants.UTTypeAppExtensionFillWebViewAction
|
||||
&& Context.ProviderType != UTType.PropertyList)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Context.Details?.HasPasswordField ?? false;
|
||||
|
||||
}
|
||||
|
||||
partial void CancelBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
LoadingController.CompleteRequest(null);
|
||||
}
|
||||
|
||||
partial void AddBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
PerformSegue("loginAddSegue", this);
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if(segue.DestinationViewController is UINavigationController navController)
|
||||
{
|
||||
if(navController.TopViewController is LoginAddViewController addLoginController)
|
||||
{
|
||||
addLoginController.Context = Context;
|
||||
addLoginController.LoginListController = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DismissModal()
|
||||
{
|
||||
DismissViewController(true, async () =>
|
||||
{
|
||||
await ((TableSource)TableView.Source).LoadItemsAsync();
|
||||
TableView.ReloadData();
|
||||
});
|
||||
}
|
||||
|
||||
public class TableSource : ExtensionTableSource
|
||||
{
|
||||
private LoginListViewController _controller;
|
||||
|
||||
public TableSource(LoginListViewController controller)
|
||||
: base(controller.Context, controller)
|
||||
{
|
||||
_controller = controller;
|
||||
}
|
||||
|
||||
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
tableView.DeselectRow(indexPath, true);
|
||||
tableView.EndEditing(true);
|
||||
|
||||
if(Items == null || Items.Count() == 0)
|
||||
{
|
||||
_controller.PerformSegue("loginAddSegue", this);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = Items.ElementAt(indexPath.Row);
|
||||
if(item == null)
|
||||
{
|
||||
_controller.LoadingController.CompleteRequest(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(_controller.CanAutoFill() && !string.IsNullOrWhiteSpace(item.Password))
|
||||
{
|
||||
string totp = null;
|
||||
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
var disableTotpCopy = storageService.GetAsync<bool?>(
|
||||
Bit.Core.Constants.DisableAutoTotpCopyKey).GetAwaiter().GetResult();
|
||||
if(!disableTotpCopy.GetValueOrDefault(false))
|
||||
{
|
||||
totp = GetTotpAsync(item).GetAwaiter().GetResult();
|
||||
}
|
||||
_controller.LoadingController.CompleteUsernamePasswordRequest(
|
||||
item.Username, item.Password, item.Fields, totp);
|
||||
}
|
||||
else if(!string.IsNullOrWhiteSpace(item.Username) || !string.IsNullOrWhiteSpace(item.Password) ||
|
||||
!string.IsNullOrWhiteSpace(item.Totp))
|
||||
{
|
||||
var sheet = Dialogs.CreateActionSheet(item.Name, _controller);
|
||||
if(!string.IsNullOrWhiteSpace(item.Username))
|
||||
{
|
||||
sheet.AddAction(UIAlertAction.Create(AppResources.CopyUsername, UIAlertActionStyle.Default, a =>
|
||||
{
|
||||
UIPasteboard clipboard = UIPasteboard.General;
|
||||
clipboard.String = item.Username;
|
||||
var alert = Dialogs.CreateMessageAlert(AppResources.CopyUsername);
|
||||
_controller.PresentViewController(alert, true, () =>
|
||||
{
|
||||
_controller.DismissViewController(true, null);
|
||||
});
|
||||
}));
|
||||
}
|
||||
if(!string.IsNullOrWhiteSpace(item.Password))
|
||||
{
|
||||
sheet.AddAction(UIAlertAction.Create(AppResources.CopyPassword, UIAlertActionStyle.Default, a =>
|
||||
{
|
||||
UIPasteboard clipboard = UIPasteboard.General;
|
||||
clipboard.String = item.Password;
|
||||
var alert = Dialogs.CreateMessageAlert(
|
||||
string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
||||
_controller.PresentViewController(alert, true, () =>
|
||||
{
|
||||
_controller.DismissViewController(true, null);
|
||||
});
|
||||
}));
|
||||
}
|
||||
if(!string.IsNullOrWhiteSpace(item.Totp))
|
||||
{
|
||||
sheet.AddAction(UIAlertAction.Create(AppResources.CopyTotp, UIAlertActionStyle.Default,
|
||||
async a =>
|
||||
{
|
||||
var totp = await GetTotpAsync(item);
|
||||
if(string.IsNullOrWhiteSpace(totp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
UIPasteboard clipboard = UIPasteboard.General;
|
||||
clipboard.String = totp;
|
||||
var alert = Dialogs.CreateMessageAlert(
|
||||
string.Format(AppResources.ValueHasBeenCopied, AppResources.VerificationCodeTotp));
|
||||
_controller.PresentViewController(alert, true, () =>
|
||||
{
|
||||
_controller.DismissViewController(true, null);
|
||||
});
|
||||
}));
|
||||
}
|
||||
sheet.AddAction(UIAlertAction.Create(AppResources.Cancel, UIAlertActionStyle.Cancel, null));
|
||||
_controller.PresentViewController(sheet, true, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var alert = Dialogs.CreateAlert(null, AppResources.NoUsernamePasswordConfigured, AppResources.Ok);
|
||||
_controller.PresentViewController(alert, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
src/iOS.Extension/LoginListViewController.designer.cs
generated
Normal file
55
src/iOS.Extension/LoginListViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,55 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("LoginListViewController")]
|
||||
partial class LoginListViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem AddBarButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem CancelBarButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UINavigationItem NavItem { get; set; }
|
||||
|
||||
[Action ("AddBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void AddBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
[Action ("CancelBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void CancelBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (AddBarButton != null) {
|
||||
AddBarButton.Dispose ();
|
||||
AddBarButton = null;
|
||||
}
|
||||
|
||||
if (CancelBarButton != null) {
|
||||
CancelBarButton.Dispose ();
|
||||
CancelBarButton = null;
|
||||
}
|
||||
|
||||
if (NavItem != null) {
|
||||
NavItem.Dispose ();
|
||||
NavItem = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +1,459 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6154.17" systemVersion="13D65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="ObA-dk-sSI">
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="64">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6153.11"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Action View Controller - Image-->
|
||||
<scene sceneID="7MM-of-jgj">
|
||||
<!--Loading View Controller-->
|
||||
<scene sceneID="42">
|
||||
<objects>
|
||||
<viewController title="Image" id="ObA-dk-sSI" customClass="ActionViewController" sceneMemberID="viewController">
|
||||
<viewController id="43" customClass="LoadingViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="qkL-Od-lgU"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="n38-gi-rB5"/>
|
||||
<viewControllerLayoutGuide type="top" id="40"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="41"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="zMn-AG-sqS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="528"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="view" contentMode="scaleToFill" id="44">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="9ga-4F-77Z">
|
||||
<rect key="frame" x="0.0" y="64" width="320" height="464"/>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="1713">
|
||||
<rect key="frame" x="66" y="316" width="282" height="44"/>
|
||||
</imageView>
|
||||
<navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NOA-Dm-cuz">
|
||||
<rect key="frame" x="0.0" y="20" width="320" height="44"/>
|
||||
<items>
|
||||
<navigationItem id="3HJ-uW-3hn">
|
||||
<barButtonItem key="leftBarButtonItem" title="Done" style="done" id="WYi-yp-eM6">
|
||||
<connections>
|
||||
<action selector="DoneClicked" destination="ObA-dk-sSI" id="Qdu-qn-U6V"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
</items>
|
||||
</navigationBar>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="NOA-Dm-cuz" secondAttribute="trailing" id="A05-Pj-hrr"/>
|
||||
<constraint firstItem="9ga-4F-77Z" firstAttribute="top" secondItem="NOA-Dm-cuz" secondAttribute="bottom" id="Fps-3D-QQW"/>
|
||||
<constraint firstItem="NOA-Dm-cuz" firstAttribute="leading" secondItem="zMn-AG-sqS" secondAttribute="leading" id="HxO-8t-aoh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9ga-4F-77Z" secondAttribute="trailing" id="Ozw-Hg-0yh"/>
|
||||
<constraint firstItem="9ga-4F-77Z" firstAttribute="leading" secondItem="zMn-AG-sqS" secondAttribute="leading" id="XH5-ld-ONA"/>
|
||||
<constraint firstItem="n38-gi-rB5" firstAttribute="top" secondItem="9ga-4F-77Z" secondAttribute="bottom" id="eQg-nn-Zy4"/>
|
||||
<constraint firstItem="NOA-Dm-cuz" firstAttribute="top" secondItem="qkL-Od-lgU" secondAttribute="bottom" id="we0-1t-bgp"/>
|
||||
<constraint firstItem="1713" firstAttribute="centerY" secondItem="44" secondAttribute="centerY" constant="-30" id="1763"/>
|
||||
<constraint firstItem="1713" firstAttribute="centerX" secondItem="44" secondAttribute="centerX" id="1764"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<size key="freeformSize" width="320" height="528"/>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="9ga-4F-77Z" id="5y6-5w-9QO"/>
|
||||
<outlet property="view" destination="zMn-AG-sqS" id="Qma-de-2ek"/>
|
||||
<segue destination="oCZ-GQ-aOK" kind="show" identifier="loginListSegue" id="1679"/>
|
||||
<segue destination="6855" kind="presentation" identifier="lockPasswordSegue" id="9874"/>
|
||||
<segue destination="1845" kind="presentation" identifier="newLoginSegue" modalPresentationStyle="fullScreen" modalTransitionStyle="coverVertical" id="10498"/>
|
||||
<segue destination="10580" kind="presentation" identifier="setupSegue" modalTransitionStyle="coverVertical" id="11089"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="X47-rx-isc" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="45" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="252" y="-124"/>
|
||||
<point key="canvasLocation" x="-374" y="560"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="63">
|
||||
<objects>
|
||||
<navigationController definesPresentationContext="YES" id="64" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" hidden="YES" contentMode="scaleToFill" translucent="NO" id="67">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="43" kind="relationship" relationship="rootViewController" id="617"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="68" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-1097" y="564"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="RvZ-Bc-vCe">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="oCZ-GQ-aOK" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="8A5-AR-QHS">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="0.0" green="0.52549019607843139" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="barTintColor" red="0.23529411764705882" green="0.55294117647058827" blue="0.73725490196078436" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textAttributes>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="2304" kind="relationship" relationship="rootViewController" id="4562"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Kkn-u3-rq1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="399" y="561"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="1844">
|
||||
<objects>
|
||||
<navigationController definesPresentationContext="YES" id="1845" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="1848">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="barTintColor" red="0.23529411764705882" green="0.55294117647058827" blue="0.73725490196078436" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textAttributes>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="2087" kind="relationship" relationship="rootViewController" id="2253"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="1849" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1932" y="-270"/>
|
||||
</scene>
|
||||
<!--Add Login-->
|
||||
<scene sceneID="2086">
|
||||
<objects>
|
||||
<tableViewController id="2087" customClass="LoginAddViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" allowsSelection="NO" rowHeight="50" sectionHeaderHeight="22" sectionFooterHeight="22" id="2088">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="sectionIndexBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<sections/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="2087" id="2089"/>
|
||||
<outlet property="delegate" destination="2087" id="2090"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Add Login" id="2252">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="3747">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="CancelBarButton_Activated:" destination="2087" id="3751"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" title="Save" id="3748">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="SaveBarButton_Activated:" destination="2087" id="3752"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="CancelBarButton" destination="3747" id="name-outlet-3747"/>
|
||||
<outlet property="NavItem" destination="2252" id="name-outlet-2252"/>
|
||||
<outlet property="SaveBarButton" destination="3748" id="name-outlet-3748"/>
|
||||
<segue destination="4574" kind="show" identifier="passwordGeneratorSegue" id="4805"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="2093" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2632" y="-276"/>
|
||||
</scene>
|
||||
<!--Logins-->
|
||||
<scene sceneID="2303">
|
||||
<objects>
|
||||
<tableViewController id="2304" customClass="LoginListViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="2305">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<prototypes>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="3763" detailTextLabel="3764" rowHeight="44" style="IBUITableViewCellStyleSubtitle" id="3761">
|
||||
<rect key="frame" x="0.0" y="22" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3761" id="3762">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="3763">
|
||||
<rect key="frame" x="20" y="4" width="35" height="21.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="3764">
|
||||
<rect key="frame" x="20" y="25.5" width="44" height="14.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="2304" id="2306"/>
|
||||
<outlet property="delegate" destination="2304" id="2307"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Logins" id="3734">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="3735">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="CancelBarButton_Activated:" destination="2304" id="3750"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="add" id="3736">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="AddBarButton_Activated:" destination="2304" id="3749"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="AddBarButton" destination="3736" id="name-outlet-3736"/>
|
||||
<outlet property="CancelBarButton" destination="3735" id="name-outlet-3735"/>
|
||||
<outlet property="NavItem" destination="3734" id="name-outlet-3734"/>
|
||||
<segue destination="1845" kind="presentation" identifier="loginAddSegue" modalPresentationStyle="fullScreen" modalTransitionStyle="coverVertical" id="3731"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="2310" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1157" y="566"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="4573">
|
||||
<objects>
|
||||
<navigationController definesPresentationContext="YES" id="4574" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="4577">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="tintColor" red="0.0" green="0.52549019607843139" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="barTintColor" red="0.23529411764705882" green="0.55294117647058827" blue="0.73725490196078436" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textAttributes>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="4576" kind="relationship" relationship="rootViewController" id="4575"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4578" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3369" y="-276"/>
|
||||
</scene>
|
||||
<!--Generate Password-->
|
||||
<scene sceneID="4579">
|
||||
<objects>
|
||||
<viewController id="4576" customClass="PasswordGeneratorViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="4571"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="4572"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="4930">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<containerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4933">
|
||||
<rect key="frame" x="0.0" y="160.5" width="414" height="575.5"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<segue destination="4912" kind="embed" id="6480"/>
|
||||
</connections>
|
||||
</containerView>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="4940">
|
||||
<rect key="frame" x="15" y="105" width="384" height="20.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="4933" secondAttribute="trailing" id="6484"/>
|
||||
<constraint firstItem="4933" firstAttribute="top" secondItem="4940" secondAttribute="bottom" constant="35" id="6485"/>
|
||||
<constraint firstItem="4933" firstAttribute="leading" secondItem="4930" secondAttribute="leading" id="6486"/>
|
||||
<constraint firstItem="4940" firstAttribute="leading" secondItem="4930" secondAttribute="leading" constant="15" id="6487"/>
|
||||
<constraint firstItem="4940" firstAttribute="top" secondItem="4571" secondAttribute="bottom" constant="35" id="6488"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4940" secondAttribute="trailing" constant="15" id="6489"/>
|
||||
<constraint firstItem="4572" firstAttribute="top" secondItem="4933" secondAttribute="bottom" id="6490"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Generate Password" id="4580">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="4807">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="CancelBarButton_Activated:" destination="4576" id="4887"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" title="Select" id="4808">
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<action selector="SelectBarButton_Activated:" destination="4576" id="4810"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="BaseView" destination="4930" id="name-outlet-4930"/>
|
||||
<outlet property="CancelBarButton" destination="4807" id="name-outlet-4807"/>
|
||||
<outlet property="NavItem" destination="4580" id="name-outlet-4580"/>
|
||||
<outlet property="OptionsContainer" destination="4933" id="name-outlet-4933"/>
|
||||
<outlet property="PasswordLabel" destination="4940" id="name-outlet-4940"/>
|
||||
<outlet property="SelectBarButton" destination="4808" id="name-outlet-4808"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4582" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="4045" y="-272"/>
|
||||
</scene>
|
||||
<!--Table View Controller-->
|
||||
<scene sceneID="4911">
|
||||
<objects>
|
||||
<tableViewController id="4912" sceneMemberID="viewController">
|
||||
<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="4913">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="575.5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="4912" id="4914"/>
|
||||
<outlet property="delegate" destination="4912" id="4915"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4918" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="4708" y="-194"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<!--Verify Fingerprint-->
|
||||
<!--Verify PIN-->
|
||||
<!--Navigation Controller-->
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="6854">
|
||||
<objects>
|
||||
<navigationController definesPresentationContext="YES" id="6855" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="6857">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="barTintColor" red="0.23529411764705882" green="0.55294117647058827" blue="0.73725490196078436" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textAttributes>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="7413" kind="relationship" relationship="rootViewController" id="8266"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6858" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="378" y="1447"/>
|
||||
</scene>
|
||||
<!--Verify Master Password-->
|
||||
<scene sceneID="7412">
|
||||
<objects>
|
||||
<tableViewController id="7413" customClass="LockPasswordViewController" sceneMemberID="viewController">
|
||||
<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="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="7413" id="7415"/>
|
||||
<outlet property="delegate" destination="7413" id="7416"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Verify Master Password" id="8265">
|
||||
<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="CancelButton" destination="8268" id="name-outlet-8268"/>
|
||||
<outlet property="MainTableView" destination="7414" id="name-outlet-7414"/>
|
||||
<outlet property="NavItem" destination="8265" id="name-outlet-8265"/>
|
||||
<outlet property="SubmitButton" destination="8269" id="name-outlet-8269"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="7419" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1089" y="1445"/>
|
||||
</scene>
|
||||
<!--Setup View Controller-->
|
||||
<scene sceneID="10573">
|
||||
<objects>
|
||||
<viewController id="10570" customClass="SetupViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="10565"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="10566"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="10575">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Extension Activated!" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="11092">
|
||||
<rect key="frame" x="15" y="100" width="384" height="20.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="11093">
|
||||
<rect key="frame" x="15" y="134.5" width="570" height="41"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="ext-icon.png" translatesAutoresizingMaskIntoConstraints="NO" id="11094">
|
||||
<rect key="frame" x="255" y="205.5" width="90" height="90"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="11092" firstAttribute="leading" secondItem="10575" secondAttribute="leading" constant="15" id="11114"/>
|
||||
<constraint firstAttribute="trailing" secondItem="11092" secondAttribute="trailing" constant="15" id="11115"/>
|
||||
<constraint firstItem="11092" firstAttribute="top" secondItem="10565" secondAttribute="bottom" constant="30" id="11116"/>
|
||||
<constraint firstItem="11093" firstAttribute="leading" secondItem="10575" secondAttribute="leading" constant="15" id="11119"/>
|
||||
<constraint firstAttribute="trailing" secondItem="11093" secondAttribute="trailing" constant="15" id="11120"/>
|
||||
<constraint firstItem="11093" firstAttribute="top" secondItem="11092" secondAttribute="bottom" constant="20" id="11121"/>
|
||||
<constraint firstItem="11094" firstAttribute="centerX" secondItem="10575" secondAttribute="centerX" id="11122"/>
|
||||
<constraint firstItem="11094" firstAttribute="top" secondItem="11093" secondAttribute="bottom" constant="30" id="11123"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="10574">
|
||||
<barButtonItem key="leftBarButtonItem" title="Back" id="11091">
|
||||
<connections>
|
||||
<action selector="BackButton_Activated:" destination="10570" id="11124"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="ActivatedLabel" destination="11092" id="name-outlet-11092"/>
|
||||
<outlet property="BackButton" destination="11091" id="name-outlet-11091"/>
|
||||
<outlet property="DescriptionLabel" destination="11093" id="name-outlet-11093"/>
|
||||
<outlet property="IconImage" destination="11094" id="name-outlet-11094"/>
|
||||
<outlet property="NavItem" destination="10574" id="name-outlet-10574"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="10576" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1129" y="-264"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="10579">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="10580" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="10583">
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="barTintColor" red="0.23529411764705882" green="0.55294117647058827" blue="0.73725490196078436" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textAttributes>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="10570" kind="relationship" relationship="rootViewController" id="10939"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="10584" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="362" y="-267"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
<resources>
|
||||
<image name="ext-icon.png" width="90" height="90"/>
|
||||
<image name="logo.png" width="282" height="44"/>
|
||||
</resources>
|
||||
</document>
|
28
src/iOS.Extension/PasswordGeneratorViewController.cs
Normal file
28
src/iOS.Extension/PasswordGeneratorViewController.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class PasswordGeneratorViewController : Core.Controllers.PasswordGeneratorViewController
|
||||
{
|
||||
public PasswordGeneratorViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
public LoginAddViewController Parent { get; set; }
|
||||
public override UINavigationItem BaseNavItem => NavItem;
|
||||
public override UIBarButtonItem BaseCancelButton => CancelBarButton;
|
||||
public override UIBarButtonItem BaseSelectBarButton => SelectBarButton;
|
||||
public override UILabel BasePasswordLabel => PasswordLabel;
|
||||
|
||||
partial void SelectBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
DismissViewController(true, () => Parent.PasswordCell.TextField.Text = PasswordLabel.Text);
|
||||
}
|
||||
|
||||
partial void CancelBarButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
DismissViewController(true, null);
|
||||
}
|
||||
}
|
||||
}
|
82
src/iOS.Extension/PasswordGeneratorViewController.designer.cs
generated
Normal file
82
src/iOS.Extension/PasswordGeneratorViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,82 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("PasswordGeneratorViewController")]
|
||||
partial class PasswordGeneratorViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView BaseView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem CancelBarButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UINavigationItem NavItem { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView OptionsContainer { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel PasswordLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem SelectBarButton { get; set; }
|
||||
|
||||
[Action ("CancelBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void CancelBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
[Action ("SelectBarButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void SelectBarButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (BaseView != null) {
|
||||
BaseView.Dispose ();
|
||||
BaseView = null;
|
||||
}
|
||||
|
||||
if (CancelBarButton != null) {
|
||||
CancelBarButton.Dispose ();
|
||||
CancelBarButton = null;
|
||||
}
|
||||
|
||||
if (NavItem != null) {
|
||||
NavItem.Dispose ();
|
||||
NavItem = null;
|
||||
}
|
||||
|
||||
if (OptionsContainer != null) {
|
||||
OptionsContainer.Dispose ();
|
||||
OptionsContainer = null;
|
||||
}
|
||||
|
||||
if (PasswordLabel != null) {
|
||||
PasswordLabel.Dispose ();
|
||||
PasswordLabel = null;
|
||||
}
|
||||
|
||||
if (SelectBarButton != null) {
|
||||
SelectBarButton.Dispose ();
|
||||
SelectBarButton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
47
src/iOS.Extension/SetupViewController.cs
Normal file
47
src/iOS.Extension/SetupViewController.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using Bit.iOS.Extension.Models;
|
||||
using UIKit;
|
||||
using Bit.iOS.Core.Controllers;
|
||||
using Bit.App.Resources;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
public partial class SetupViewController : ExtendedUIViewController
|
||||
{
|
||||
public SetupViewController(IntPtr handle)
|
||||
: base(handle)
|
||||
{ }
|
||||
|
||||
public Context Context { get; set; }
|
||||
public LoadingViewController LoadingController { get; set; }
|
||||
|
||||
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()
|
||||
{
|
||||
View.BackgroundColor = new UIColor(red: 0.94f, green: 0.94f, blue: 0.96f, alpha: 1.0f);
|
||||
var descriptor = UIFontDescriptor.PreferredBody;
|
||||
DescriptionLabel.Text = $@"{AppResources.ExtensionSetup}
|
||||
|
||||
{AppResources.ExtensionSetup2}";
|
||||
DescriptionLabel.Font = UIFont.FromDescriptor(descriptor, descriptor.PointSize);
|
||||
DescriptionLabel.TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f);
|
||||
|
||||
ActivatedLabel.Text = AppResources.ExtensionActivated;
|
||||
ActivatedLabel.Font = UIFont.FromDescriptor(descriptor, descriptor.PointSize * 1.3f);
|
||||
|
||||
BackButton.Title = AppResources.Back;
|
||||
base.ViewDidLoad();
|
||||
}
|
||||
|
||||
partial void BackButton_Activated(UIBarButtonItem sender)
|
||||
{
|
||||
LoadingController.CompleteRequest(null);
|
||||
}
|
||||
}
|
||||
}
|
69
src/iOS.Extension/SetupViewController.designer.cs
generated
Normal file
69
src/iOS.Extension/SetupViewController.designer.cs
generated
Normal file
|
@ -0,0 +1,69 @@
|
|||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Extension
|
||||
{
|
||||
[Register ("SetupViewController")]
|
||||
partial class SetupViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel ActivatedLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIBarButtonItem BackButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel DescriptionLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIImageView IconImage { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UINavigationItem NavItem { get; set; }
|
||||
|
||||
[Action ("BackButton_Activated:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BackButton_Activated (UIKit.UIBarButtonItem sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (ActivatedLabel != null) {
|
||||
ActivatedLabel.Dispose ();
|
||||
ActivatedLabel = null;
|
||||
}
|
||||
|
||||
if (BackButton != null) {
|
||||
BackButton.Dispose ();
|
||||
BackButton = null;
|
||||
}
|
||||
|
||||
if (DescriptionLabel != null) {
|
||||
DescriptionLabel.Dispose ();
|
||||
DescriptionLabel = null;
|
||||
}
|
||||
|
||||
if (IconImage != null) {
|
||||
IconImage.Dispose ();
|
||||
IconImage = null;
|
||||
}
|
||||
|
||||
if (NavItem != null) {
|
||||
NavItem.Dispose ();
|
||||
NavItem = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,13 +64,37 @@
|
|||
<AppExtensionDebugBundleId />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="LoadingViewController.cs" />
|
||||
<Compile Include="LoadingViewController.designer.cs">
|
||||
<DependentUpon>LoadingViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LockPasswordViewController.cs" />
|
||||
<Compile Include="LockPasswordViewController.designer.cs">
|
||||
<DependentUpon>LockPasswordViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LoginAddViewController.cs" />
|
||||
<Compile Include="LoginAddViewController.designer.cs">
|
||||
<DependentUpon>LoginAddViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LoginListViewController.cs" />
|
||||
<Compile Include="LoginListViewController.designer.cs">
|
||||
<DependentUpon>LoginListViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="AppDelegate.cs" />
|
||||
<Compile Include="SetupViewController.cs" />
|
||||
<Compile Include="SetupViewController.designer.cs">
|
||||
<DependentUpon>SetupViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Info.plist" />
|
||||
<None Include="Entitlements.plist" />
|
||||
<Compile Include="Models\Context.cs" />
|
||||
<Compile Include="Models\FillScript.cs" />
|
||||
<Compile Include="Models\PageDetails.cs" />
|
||||
<Compile Include="PasswordGeneratorViewController.cs" />
|
||||
<Compile Include="PasswordGeneratorViewController.designer.cs">
|
||||
<DependentUpon>PasswordGeneratorViewController.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ActionViewController.designer.cs">
|
||||
<DependentUpon>ActionViewController.cs</DependentUpon>
|
||||
|
@ -91,6 +115,10 @@
|
|||
<Project>{ee44c6a1-2a85-45fe-8d9b-bf1d5f88809c}</Project>
|
||||
<Name>App</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{4b8a8c41-9820-4341-974c-41e65b7f4366}</Project>
|
||||
<Name>Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\iOS.Core\iOS.Core.csproj">
|
||||
<Project>{e71f3053-056c-4381-9638-048ed73bdff6}</Project>
|
||||
<Name>iOS.Core</Name>
|
||||
|
|
Loading…
Reference in a new issue