diff --git a/External/Pearl b/External/Pearl
index 17a3f485..d8c2fa37 160000
--- a/External/Pearl
+++ b/External/Pearl
@@ -1 +1 @@
-Subproject commit 17a3f485d1056976f55d0311d20ce4a693a62748
+Subproject commit d8c2fa3755d1f440cd5eaa980adffef08a805b25
diff --git a/MasterPassword/ObjC/MPAlgorithmV0.m b/MasterPassword/ObjC/MPAlgorithmV0.m
index 7318e11b..1e7bf8ea 100644
--- a/MasterPassword/ObjC/MPAlgorithmV0.m
+++ b/MasterPassword/ObjC/MPAlgorithmV0.m
@@ -35,7 +35,7 @@
NSError *error = nil;
NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
- migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", MPAlgorithmDefaultVersion, user];
+ migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
NSArray *migrationElements = [user.managedObjectContext executeFetchRequest:migrationRequest error:&error];
if (!migrationElements) {
err(@"While looking for elements to migrate: %@", error);
diff --git a/MasterPassword/ObjC/MPEntities.h b/MasterPassword/ObjC/MPEntities.h
index 779da898..f27429b4 100644
--- a/MasterPassword/ObjC/MPEntities.h
+++ b/MasterPassword/ObjC/MPEntities.h
@@ -15,9 +15,9 @@
#define MPAvatarCount 19
-@interface NSManagedObject (MP)
+@interface NSManagedObjectContext(MP)
-- (BOOL)saveContext;
+- (BOOL)saveToStore;
@end
diff --git a/MasterPassword/ObjC/MPEntities.m b/MasterPassword/ObjC/MPEntities.m
index 654cfb9d..e95e00f1 100644
--- a/MasterPassword/ObjC/MPEntities.m
+++ b/MasterPassword/ObjC/MPEntities.m
@@ -9,22 +9,17 @@
#import "MPEntities.h"
#import "MPAppDelegate.h"
-@implementation NSManagedObject (MP)
+@implementation NSManagedObjectContext (MP)
-- (BOOL)saveContext {
+- (BOOL)saveToStore {
NSError *error;
- NSManagedObjectContext *moc = [self managedObjectContext];
- if (![moc save:&error]) {
- err(@"While saving %@: %@", NSStringFromClass([self class]), error);
- return NO;
- }
- if (![moc.parentContext save:&error]) {
- err(@"While saving parent %@: %@", NSStringFromClass([self class]), error);
+ if (![self save:&error]) {
+ err(@"While saving: %@", NSStringFromClass([self class]), error);
return NO;
}
- return YES;
+ return !self.parentContext || [self.parentContext saveToStore];
}
@end
diff --git a/MasterPassword/ObjC/MPTypes.h b/MasterPassword/ObjC/MPTypes.h
index cb72989b..9ddc34fc 100644
--- a/MasterPassword/ObjC/MPTypes.h
+++ b/MasterPassword/ObjC/MPTypes.h
@@ -52,6 +52,7 @@ typedef enum {
#define MPCheckpointUseType @"MPCheckpointUseType"
#define MPCheckpointDeleteElement @"MPCheckpointDeleteElement"
#define MPCheckpointShowGuide @"MPCheckpointShowGuide"
+#define MPCheckpointShowSetup @"MPCheckpointShowSetup"
#define MPCheckpointChangeMP @"MPCheckpointChangeMP"
#define MPCheckpointMPErrorUbiquity @"MPCheckpointMPErrorUbiquity"
#define MPCheckpointLocalStoreReset @"MPCheckpointLocalStoreReset"
diff --git a/MasterPassword/ObjC/MasterPassword.xcdatamodeld/.xccurrentversion b/MasterPassword/ObjC/MasterPassword.xcdatamodeld/.xccurrentversion
index 6bc55904..000aa55d 100644
--- a/MasterPassword/ObjC/MasterPassword.xcdatamodeld/.xccurrentversion
+++ b/MasterPassword/ObjC/MasterPassword.xcdatamodeld/.xccurrentversion
@@ -3,6 +3,6 @@
_XCCurrentVersionName
- MasterPassword 1.xcdatamodel
+ MasterPassword 4.xcdatamodel
diff --git a/MasterPassword/ObjC/iOS/MPAppDelegate.h b/MasterPassword/ObjC/iOS/MPAppDelegate.h
index 02d548d6..a5c545ed 100644
--- a/MasterPassword/ObjC/iOS/MPAppDelegate.h
+++ b/MasterPassword/ObjC/iOS/MPAppDelegate.h
@@ -17,9 +17,10 @@
@property (nonatomic, readonly) GPPShare *googlePlus;
- (void)showGuide;
+- (void)showSetup;
- (void)showFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController;
- (void)export;
-- (void)changeMasterPasswordFor:(MPUserEntity *)user didResetBlock:(void(^)(void))didReset;
+- (void)changeMasterPasswordFor:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc didResetBlock:(void(^)(void))didReset;
@end
diff --git a/MasterPassword/ObjC/iOS/MPAppDelegate.m b/MasterPassword/ObjC/iOS/MPAppDelegate.m
index b61d16fe..316a11ba 100644
--- a/MasterPassword/ObjC/iOS/MPAppDelegate.m
+++ b/MasterPassword/ObjC/iOS/MPAppDelegate.m
@@ -188,14 +188,6 @@
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
*/
- [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil queue:nil
- usingBlock:^(NSNotification *note) {
- if ([[note.userInfo objectForKey:@"animated"] boolValue])
- [self.navigationController performSegueWithIdentifier:@"MP_Unlock" sender:nil];
- else
- [self.navigationController presentViewController:[self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"MPUnlockViewController"]
- animated:NO completion:nil];
- }];
[[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil queue:nil usingBlock:
^(NSNotification *note) {
if ([[MPiOSConfig get].sendInfo boolValue]) {
@@ -207,7 +199,7 @@
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].iCloudDecided boolValue] forKey:@"iCloudDecided"];
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].sendInfo boolValue] forKey:@"sendInfo"];
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].helpHidden boolValue] forKey:@"helpHidden"];
- [[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].showQuickStart boolValue] forKey:@"showQuickStart"];
+ [[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].showSetup boolValue] forKey:@"showQuickStart"];
[[Crashlytics sharedInstance] setBoolValue:[[PearlConfig get].firstRun boolValue] forKey:@"firstRun"];
[[Crashlytics sharedInstance] setIntValue:[[PearlConfig get].launchCount intValue] forKey:@"launchCount"];
[[Crashlytics sharedInstance] setBoolValue:[[PearlConfig get].askForReviews boolValue] forKey:@"askForReviews"];
@@ -220,7 +212,7 @@
[TestFlight addCustomEnvironmentInformation:[[MPConfig get].iCloudDecided boolValue]? @"YES": @"NO" forKey:@"iCloudDecided"];
[TestFlight addCustomEnvironmentInformation:[[MPiOSConfig get].sendInfo boolValue]? @"YES": @"NO" forKey:@"sendInfo"];
[TestFlight addCustomEnvironmentInformation:[[MPiOSConfig get].helpHidden boolValue]? @"YES": @"NO" forKey:@"helpHidden"];
- [TestFlight addCustomEnvironmentInformation:[[MPiOSConfig get].showQuickStart boolValue]? @"YES": @"NO"
+ [TestFlight addCustomEnvironmentInformation:[[MPiOSConfig get].showSetup boolValue]? @"YES": @"NO"
forKey:@"showQuickStart"];
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].firstRun boolValue]? @"YES": @"NO" forKey:@"firstRun"];
[TestFlight addCustomEnvironmentInformation:[[PearlConfig get].launchCount description] forKey:@"launchCount"];
@@ -237,7 +229,7 @@
@"iCloudDecided" : [[MPConfig get].iCloudDecided boolValue]? @"YES": @"NO",
@"sendInfo" : [[MPiOSConfig get].sendInfo boolValue]? @"YES": @"NO",
@"helpHidden" : [[MPiOSConfig get].helpHidden boolValue]? @"YES": @"NO",
- @"showQuickStart" : [[MPiOSConfig get].showQuickStart boolValue]? @"YES": @"NO",
+ @"showQuickStart" : [[MPiOSConfig get].showSetup boolValue]? @"YES": @"NO",
@"firstRun" : [[PearlConfig get].firstRun boolValue]? @"YES": @"NO",
@"launchCount" : NilToNSNull([[PearlConfig get].launchCount description]),
@"askForReviews" : [[PearlConfig get].askForReviews boolValue]? @"YES": @"NO",
@@ -268,6 +260,9 @@
inf(@"Started up with device identifier: %@", [PearlKeyChain deviceIdentifier]);
+ if ([[MPiOSConfig get].showSetup boolValue])
+ [[MPAppDelegate get] showSetup];
+
return YES;
}
@@ -438,6 +433,16 @@
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointShowGuide attributes:nil];
}
+- (void)showSetup {
+
+ [self.navigationController performSegueWithIdentifier:@"MP_Setup" sender:self];
+
+#ifdef TESTFLIGHT_SDK_VERSION
+ [TestFlight passCheckpoint:MPCheckpointShowSetup];
+#endif
+ [[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointShowSetup attributes:nil];
+}
+
- (void)showFeedback {
[self showFeedbackWithLogs:NO forVC:nil];
@@ -575,7 +580,7 @@
nil];
}
-- (void)changeMasterPasswordFor:(MPUserEntity *)user didResetBlock:(void (^)(void))didReset {
+- (void)changeMasterPasswordFor:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc didResetBlock:(void (^)(void))didReset {
[PearlAlert showAlertWithTitle:@"Changing Master Password"
message:
@@ -587,12 +592,13 @@
if (buttonIndex == [alert cancelButtonIndex])
return;
- [user.managedObjectContext performBlock:^{
+ [moc performBlock:^{
inf(@"Unsetting master password for: %@.", user.userID);
user.keyID = nil;
[self forgetSavedKeyFor:user];
- [self signOutAnimated:YES];
+ [moc saveToStore];
+ [self signOutAnimated:YES];
if (didReset)
didReset();
diff --git a/MasterPassword/ObjC/iOS/MPGuideViewController.h b/MasterPassword/ObjC/iOS/MPGuideViewController.h
index a7e4e656..9669ca5e 100644
--- a/MasterPassword/ObjC/iOS/MPGuideViewController.h
+++ b/MasterPassword/ObjC/iOS/MPGuideViewController.h
@@ -10,9 +10,6 @@
@interface MPGuideViewController : UIViewController
-@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
-@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
-
- (IBAction)close;
@end
diff --git a/MasterPassword/ObjC/iOS/MPGuideViewController.m b/MasterPassword/ObjC/iOS/MPGuideViewController.m
index 3b2f7adf..119ab18e 100644
--- a/MasterPassword/ObjC/iOS/MPGuideViewController.m
+++ b/MasterPassword/ObjC/iOS/MPGuideViewController.m
@@ -21,18 +21,9 @@
return UIInterfaceOrientationPortrait;
}
-- (void)viewDidLoad {
-
- [super viewDidLoad];
-
- [self.scrollView autoSizeContent];
-}
-
- (void)viewWillAppear:(BOOL)animated {
inf(@"Guide will appear.");
- [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
-
[super viewWillAppear:animated];
}
@@ -46,10 +37,6 @@
- (void)viewWillDisappear:(BOOL)animated {
inf(@"Guide will disappear.");
- [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
-
- [MPiOSConfig get].showQuickStart = @NO;
-
[super viewWillDisappear:animated];
}
@@ -58,12 +45,4 @@
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
-- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView_ {
-
- NSInteger page = (NSInteger)(self.scrollView.contentOffset.x / self.scrollView.bounds.size.width);
-
- self.pageControl.currentPage = page;
- self.pageControl.hidden = (page == self.pageControl.numberOfPages - 1);
-}
-
@end
diff --git a/MasterPassword/ObjC/iOS/MPMainViewController.m b/MasterPassword/ObjC/iOS/MPMainViewController.m
index 114a58ca..d4267702 100644
--- a/MasterPassword/ObjC/iOS/MPMainViewController.m
+++ b/MasterPassword/ObjC/iOS/MPMainViewController.m
@@ -25,17 +25,17 @@
#pragma mark - View lifecycle
- (BOOL)shouldAutorotate {
-
+
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
-
+
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
-
+
return UIInterfaceOrientationPortrait;
}
@@ -91,30 +91,24 @@
[self showToolTip:@"Password outdated. Tap to upgrade it." withIcon:nil];
}];
}];
- [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil queue:nil
- usingBlock:^void(NSNotification *note) {
- _activeElementOID = nil;
- self.suppressOutdatedAlert = NO;
- [self updateAnimated:NO];
- }];
+ [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil queue:nil usingBlock:
+ ^(NSNotification *note) {
+ _activeElementOID = nil;
+ self.suppressOutdatedAlert = NO;
+ [self updateAnimated:NO];
+ [self.navigationController popToRootViewControllerAnimated:[[note.userInfo objectForKey:@"animated"] boolValue]];
+ }];
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
- if ([[MPiOSConfig get].showQuickStart boolValue])
- [[MPAppDelegate get] showGuide];
- if (![MPAppDelegate get].activeUser)
- // FIXME: Remove either this one or the one in -viewDidAppear:
- [self presentViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"MPUnlockViewController"]
- animated:animated completion:nil];
-
-
[self activeElementDo:^(MPElementEntity *activeElement) {
if (activeElement.user != [MPAppDelegate get].activeUser)
_activeElementOID = nil;
}];
+
self.searchDisplayController.searchBar.text = nil;
self.alertContainer.alpha = 0;
self.outdatedAlertContainer.alpha = 0;
@@ -131,23 +125,21 @@
- (void)viewDidAppear:(BOOL)animated {
inf(@"Main will appear");
-
+
// Sometimes, the search bar gets stuck in some sort of first-responder mode that it can't get out of...
[[self.view.window findFirstResponderInHierarchy] resignFirstResponder];
// Needed for when we appear after a modal VC dismisses:
// We can't present until the other modal VC has been fully dismissed and presenting in -viewWillAppear: will fail.
- if ([MPAppDelegate get].activeUser)
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
- if ([MPAlgorithmDefault migrateUser:[MPAppDelegate get].activeUser] && !self.suppressOutdatedAlert)
- [UIView animateWithDuration:0.3f animations:^{
- self.outdatedAlertContainer.alpha = 1;
- self.suppressOutdatedAlert = YES;
- }];
- });
- else
- [self presentViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"MPUnlockViewController"]
- animated:animated completion:nil];
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
+ MPUserEntity *activeUser = [MPAppDelegate get].activeUser;
+ if ([MPAlgorithmDefault migrateUser:activeUser] && !self.suppressOutdatedAlert)
+ [UIView animateWithDuration:0.3f animations:^{
+ self.outdatedAlertContainer.alpha = 1;
+ self.suppressOutdatedAlert = YES;
+ }];
+ [activeUser saveContext];
+ });
if (![[MPiOSConfig get].actionsTipShown boolValue])
[UIView animateWithDuration:animated? 0.3f: 0 animations:^{
@@ -686,19 +678,20 @@
if (!warning)
return;
- [self changeActiveElementWithWarning:warning
- do:^BOOL(MPElementEntity *activeElement) {
- inf(@"Explicitly migrating element: %@", activeElement);
- [activeElement migrateExplicitly:YES];
+ [self changeActiveElementWithWarning:warning do:
+ ^BOOL(MPElementEntity *activeElement) {
+ inf(@"Explicitly migrating element: %@", activeElement);
+ [activeElement migrateExplicitly:YES];
#ifdef TESTFLIGHT_SDK_VERSION
- [TestFlight passCheckpoint:MPCheckpointExplicitMigration];
+ [TestFlight passCheckpoint:MPCheckpointExplicitMigration];
#endif
- [[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointExplicitMigration
- attributes:@{@"type" : activeElement.typeName,
- @"version" : @(activeElement.version)}];
- return YES;
- }];
+ [[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointExplicitMigration attributes:@{
+ @"type" : activeElement.typeName,
+ @"version" : @(activeElement.version)
+ }];
+ return YES;
+ }];
}
- (IBAction)searchOutdatedElements {
@@ -736,63 +729,59 @@
- (IBAction)action:(id)sender {
[PearlSheet showSheetWithTitle:nil viewStyle:UIActionSheetStyleAutomatic
- initSheet:nil
- tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
- if (buttonIndex == [sheet cancelButtonIndex])
- return;
+ initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
+ if (buttonIndex == [sheet cancelButtonIndex])
+ return;
- switch (buttonIndex - [sheet firstOtherButtonIndex]) {
- case 0: {
- inf(@"Action: FAQ");
- [self setHelpChapter:@"faq"];
- [self setHelpHidden:NO animated:YES];
- break;
- }
- case 1: {
- inf(@"Action: Guide");
- [[MPAppDelegate get] showGuide];
- break;
- }
- case 2: {
- inf(@"Action: Preferences");
- [self performSegueWithIdentifier:@"MP_UserProfile" sender:self];
- break;
- }
- case 3: {
- inf(@"Action: Other Apps");
- [self performSegueWithIdentifier:@"MP_OtherApps" sender:self];
- break;
- }
+ switch (buttonIndex - [sheet firstOtherButtonIndex]) {
+ case 0: {
+ inf(@"Action: FAQ");
+ [self setHelpChapter:@"faq"];
+ [self setHelpHidden:NO animated:YES];
+ break;
+ }
+ case 1: {
+ inf(@"Action: Guide");
+ [[MPAppDelegate get] showGuide];
+ break;
+ }
+ case 2: {
+ inf(@"Action: Preferences");
+ [self performSegueWithIdentifier:@"MP_UserProfile" sender:self];
+ break;
+ }
+ case 3: {
+ inf(@"Action: Other Apps");
+ [self performSegueWithIdentifier:@"MP_OtherApps" sender:self];
+ break;
+ }
//#if defined(ADHOC) && defined(TESTFLIGHT_SDK_VERSION)
// case 4: {
// inf(@"Action: Feedback via TestFlight");
// [TestFlight openFeedbackView];
// break;
// }
-// case 5:
//#else
- case 4: {
- inf(@"Action: Feedback via Mail");
- [[MPAppDelegate get] showFeedbackWithLogs:YES forVC:self];
- break;
- }
- case 5:
+ case 4: {
+ inf(@"Action: Feedback via Mail");
+ [[MPAppDelegate get] showFeedbackWithLogs:YES forVC:self];
+ break;
+ }
//#endif
- {
- inf(@"Action: Sign out");
- [[MPAppDelegate get] signOutAnimated:YES];
- break;
- }
- default: {
- wrn(@"Unsupported action: %u", buttonIndex - [sheet firstOtherButtonIndex]);
- break;
- }
- }
- }
+ default: {
+ wrn(@"Unsupported action: %u", buttonIndex - [sheet firstOtherButtonIndex]);
+ break;
+ }
+ }
+ }
cancelTitle:[PearlStrings get].commonButtonCancel destructiveTitle:nil otherTitles:
- @"FAQ", @"Tutorial", @"Preferences", @"Other Apps", @"Feedback", @"Sign Out",
- nil];
+ @"? FAQ",
+ @"ℹ Quick Guide",
+ @"⚙ Preferences",
+ @"⬇ Other Apps",
+ @"✉ Feedback",
+ nil];
}
- (MPElementType)selectedType {
diff --git a/MasterPassword/ObjC/iOS/MPPreferencesViewController.m b/MasterPassword/ObjC/iOS/MPPreferencesViewController.m
index 825bc20f..e18ad705 100644
--- a/MasterPassword/ObjC/iOS/MPPreferencesViewController.m
+++ b/MasterPassword/ObjC/iOS/MPPreferencesViewController.m
@@ -114,8 +114,7 @@
else
if (cell == self.changeMPCell) {
MPUserEntity *activeUser = [MPAppDelegate get].activeUser;
- [[MPAppDelegate get] changeMasterPasswordFor:activeUser didResetBlock:nil];
- [activeUser saveContext];
+ [[MPAppDelegate get] changeMasterPasswordFor:activeUser inContext:activeUser.managedObjectContext didResetBlock:nil];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
diff --git a/MasterPassword/ObjC/iOS/MPSetupViewController.h b/MasterPassword/ObjC/iOS/MPSetupViewController.h
new file mode 100644
index 00000000..7c8bd08e
--- /dev/null
+++ b/MasterPassword/ObjC/iOS/MPSetupViewController.h
@@ -0,0 +1,24 @@
+/**
+ * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
+ *
+ * See the enclosed file LICENSE for license information (LGPLv3). If you did
+ * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * @author Maarten Billemont
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+
+//
+// MPSetupViewController.h
+// MPSetupViewController
+//
+// Created by lhunath on 2013-04-11.
+// Copyright, lhunath (Maarten Billemont) 2013. All rights reserved.
+//
+
+#import
+
+@interface MPSetupViewController : UIViewController
+- (IBAction)close:(UIBarButtonItem *)sender;
+- (IBAction)showGuide:(UIBarButtonItem *)sender;
+@end
diff --git a/MasterPassword/ObjC/iOS/MPSetupViewController.m b/MasterPassword/ObjC/iOS/MPSetupViewController.m
new file mode 100644
index 00000000..edc09c4b
--- /dev/null
+++ b/MasterPassword/ObjC/iOS/MPSetupViewController.m
@@ -0,0 +1,38 @@
+/**
+ * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
+ *
+ * See the enclosed file LICENSE for license information (LGPLv3). If you did
+ * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * @author Maarten Billemont
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+
+//
+// MPSetupViewController.h
+// MPSetupViewController
+//
+// Created by lhunath on 2013-04-11.
+// Copyright, lhunath (Maarten Billemont) 2013. All rights reserved.
+//
+
+#import "MPSetupViewController.h"
+#import "MPAppDelegate.h"
+
+@implementation MPSetupViewController
+
+- (IBAction)close:(UIBarButtonItem *)sender {
+
+ [MPiOSConfig get].showSetup = @NO;
+ [self dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (IBAction)showGuide:(UIBarButtonItem *)sender {
+
+ [MPiOSConfig get].showSetup = @NO;
+ [self dismissViewControllerAnimated:YES completion:^{
+ [[MPAppDelegate get] showGuide];
+ }];
+}
+
+@end
diff --git a/MasterPassword/ObjC/iOS/MPUnlockViewController.m b/MasterPassword/ObjC/iOS/MPUnlockViewController.m
index 9a588e3b..e6bc04e0 100644
--- a/MasterPassword/ObjC/iOS/MPUnlockViewController.m
+++ b/MasterPassword/ObjC/iOS/MPUnlockViewController.m
@@ -26,7 +26,7 @@
NSManagedObjectID *_selectedUserOID;
}
-- (void)initializeAvatarAlert:(UIAlertView *)alert forUser:(MPUserEntity *)user {
+- (void)initializeAvatarAlert:(UIAlertView *)alert forUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc {
UIScrollView *alertAvatarScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(12, 30, 260, 150)];
alertAvatarScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
@@ -59,7 +59,7 @@
} options:0];
[avatar onSelect:^(BOOL selected) {
if (selected)
- [user.managedObjectContext performBlock:^{
+ [moc performBlock:^{
user.avatar = (unsigned)avatar.tag;
}];
} options:0];
@@ -164,9 +164,12 @@
- (void)viewWillAppear:(BOOL)animated {
+ inf(@"Lock screen will appear");
+ [self.navigationController setNavigationBarHidden:YES animated:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
- inf(@"Lock screen will appear");
+ [[MPAppDelegate get] signOutAnimated:NO];
+
_selectedUserOID = nil;
[self updateUsers];
@@ -196,6 +199,9 @@
inf(@"Lock screen will disappear");
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
+ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+ [self.navigationController setNavigationBarHidden:NO animated:animated];
+ }];
[super viewWillDisappear:animated];
}
@@ -288,7 +294,7 @@
[self.passwordField resignFirstResponder];
else
if ([[MPAppDelegate get] signInAsUser:selectedUser usingMasterPassword:nil]) {
- [self dismissViewControllerAnimated:YES completion:nil];
+ [self performSegueWithIdentifier:@"MP_Unlock" sender:self];
return;
}
@@ -301,19 +307,17 @@
- (void)didSelectNewUserAvatar:(UIButton *)newUserAvatar {
[MPAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
- MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class])
- inManagedObjectContext:moc];
+ MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class]) inManagedObjectContext:moc];
- [self showNewUserNameAlertFor:newUser completion:^(BOOL finished) {
+ [self showNewUserNameAlertFor:newUser inContext:moc completion:^(BOOL finished) {
newUserAvatar.selected = NO;
-
- if (finished)
- [newUser saveContext];
+ self.selectedUser = newUser;
}];
}];
}
-- (void)showNewUserNameAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion {
+- (void)showNewUserNameAlertFor:(MPUserEntity *)newUser inContext:(NSManagedObjectContext *)moc
+ completion:(void (^)(BOOL finished))completion {
dispatch_async(dispatch_get_main_queue(), ^{
[PearlAlert showAlertWithTitle:@"Enter Your Name"
@@ -333,40 +337,42 @@
if (![alert textFieldAtIndex:0].text.length) {
[PearlAlert showAlertWithTitle:@"Name Is Required" message:nil viewStyle:UIAlertViewStyleDefault initAlert:nil
tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
- [newUser.managedObjectContext performBlock:^{
- [self showNewUserNameAlertFor:newUser completion:completion];
+ [moc performBlock:^{
+ [self showNewUserNameAlertFor:newUser inContext:moc completion:completion];
}];
} cancelTitle:@"Try Again" otherTitles:nil];
return;
}
-
+
// Save
- [newUser.managedObjectContext performBlock:^{
+ [moc performBlock:^{
newUser.name = [alert textFieldAtIndex:0].text;
- [self showNewUserAvatarAlertFor:newUser completion:completion];
+ [self showNewUserAvatarAlertFor:newUser inContext:moc completion:completion];
}];
}
cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonSave, nil];
});
}
-- (void)showNewUserAvatarAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion {
+- (void)showNewUserAvatarAlertFor:(MPUserEntity *)newUser inContext:(NSManagedObjectContext *)moc
+ completion:(void (^)(BOOL finished))completion {
[PearlAlert showAlertWithTitle:@"Choose Your Avatar"
message:@"\n\n\n\n\n\n" viewStyle:UIAlertViewStyleDefault
initAlert:^(UIAlertView *_alert, UITextField *_firstField) {
- [self initializeAvatarAlert:_alert forUser:newUser];
+ [self initializeAvatarAlert:_alert forUser:newUser inContext:moc];
}
tappedButtonBlock:^(UIAlertView *_alert, NSInteger _buttonIndex) {
// Okay
- [newUser.managedObjectContext performBlock:^{
- [self showNewUserConfirmationAlertFor:newUser completion:completion];
+ [moc performBlock:^{
+ [self showNewUserConfirmationAlertFor:newUser inContext:moc completion:completion];
}];
} cancelTitle:nil otherTitles:[PearlStrings get].commonButtonOkay, nil];
}
-- (void)showNewUserConfirmationAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion {
+- (void)showNewUserConfirmationAlertFor:(MPUserEntity *)newUser inContext:(NSManagedObjectContext *)moc
+ completion:(void (^)(BOOL finished))completion {
[PearlAlert showAlertWithTitle:@"Is this correct?"
message:
@@ -378,15 +384,15 @@
}
tappedButtonBlock:^void(UIAlertView *__alert, NSInteger __buttonIndex) {
if (__buttonIndex == [__alert cancelButtonIndex]) {
- [newUser.managedObjectContext performBlock:^{
- [self showNewUserNameAlertFor:newUser completion:completion];
+ [moc performBlock:^{
+ [self showNewUserNameAlertFor:newUser inContext:moc completion:completion];
}];
return;
}
// Confirm
+ [moc saveToStore];
completion(YES);
- self.selectedUser = newUser;
[self updateUsers];
}
@@ -556,7 +562,7 @@
dispatch_async(dispatch_get_main_queue(), ^{
if (unlocked)
- [self dismissViewControllerAnimated:YES completion:nil];
+ [self performSegueWithIdentifier:@"MP_Unlock" sender:self];
else {
if (self.passwordField.text.length)
@@ -782,6 +788,7 @@
if (!targetedUser)
return;
+ NSManagedObjectContext *moc = targetedUser.managedObjectContext;
[PearlSheet showSheetWithTitle:targetedUser.name
viewStyle:UIActionSheetStyleBlackTranslucent
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
@@ -789,9 +796,9 @@
return;
if (buttonIndex == [sheet destructiveButtonIndex]) {
- [targetedUser.managedObjectContext performBlock:^{
- [targetedUser.managedObjectContext deleteObject:targetedUser];
- [targetedUser saveContext];
+ [moc performBlock:^{
+ [moc deleteObject:targetedUser];
+ [moc saveToStore];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateUsers];
@@ -801,7 +808,7 @@
}
if (buttonIndex == [sheet firstOtherButtonIndex])
- [targetedUser.managedObjectContext performBlock:^{
+ [moc performBlock:^{
[[MPAppDelegate get] changeMasterPasswordFor:targetedUser didResetBlock:^{
dispatch_async(dispatch_get_main_queue(), ^{
[[self avatarForUser:targetedUser] setSelected:YES];
diff --git a/MasterPassword/ObjC/iOS/MPiOSConfig.h b/MasterPassword/ObjC/iOS/MPiOSConfig.h
index b66083ee..a363dca7 100644
--- a/MasterPassword/ObjC/iOS/MPiOSConfig.h
+++ b/MasterPassword/ObjC/iOS/MPiOSConfig.h
@@ -12,7 +12,7 @@
@property (nonatomic, retain) NSNumber *helpHidden;
@property (nonatomic, retain) NSNumber *siteInfoHidden;
-@property (nonatomic, retain) NSNumber *showQuickStart;
+@property (nonatomic, retain) NSNumber *showSetup;
@property (nonatomic, retain) NSNumber *actionsTipShown;
@property (nonatomic, retain) NSNumber *typeTipShown;
@property (nonatomic, retain) NSNumber *loginNameTipShown;
diff --git a/MasterPassword/ObjC/iOS/MPiOSConfig.m b/MasterPassword/ObjC/iOS/MPiOSConfig.m
index dfb2c350..f36f7695 100644
--- a/MasterPassword/ObjC/iOS/MPiOSConfig.m
+++ b/MasterPassword/ObjC/iOS/MPiOSConfig.m
@@ -7,7 +7,7 @@
//
@implementation MPiOSConfig
-@dynamic sendInfo, helpHidden, siteInfoHidden, showQuickStart, actionsTipShown, typeTipShown, loginNameTipShown;
+@dynamic sendInfo, helpHidden, siteInfoHidden, showSetup, actionsTipShown, typeTipShown, loginNameTipShown;
- (id)init {
@@ -16,7 +16,7 @@
[self.defaults registerDefaults:@{ NSStringFromSelector(@selector(helpHidden)): @NO,
NSStringFromSelector(@selector(siteInfoHidden)): @YES,
- NSStringFromSelector(@selector(showQuickStart)): @YES,
+ NSStringFromSelector(@selector(showSetup)): @YES,
NSStringFromSelector(@selector(iTunesID)): @"510296984",
NSStringFromSelector(@selector(actionsTipShown)): PearlBoolNot(self.firstRun),
NSStringFromSelector(@selector(typeTipShown)): PearlBoolNot(self.firstRun),
diff --git a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard
index 7659bcfc..e4afda33 100644
--- a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard
+++ b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard
@@ -9,7 +9,7 @@
-
+
@@ -474,18 +474,18 @@ Your passwords will be AES-encrypted with your master password.
-
+
-
+
-
+
@@ -629,7 +629,7 @@ Your passwords will be AES-encrypted with your master password.
-
+
@@ -664,7 +664,7 @@ Your passwords will be AES-encrypted with your master password.
-
+
@@ -830,8 +830,8 @@ Your passwords will be AES-encrypted with your master password.
-
-
+
+
@@ -908,8 +908,8 @@ These sites should be upgraded and their account's passwords updated as soon as
-
-
+
+
@@ -966,6 +966,8 @@ L4m3P4sSw0rD
+
+
@@ -1025,210 +1027,7 @@ L4m3P4sSw0rD
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Welcome to Master Password.
-
-The goal of this application is to
-secure your online life.
-
-To accomplish this,
-over the course of the next few weeks
-you will slowly change the passwords
-of all your online accounts
-to secure random passwords
-generated by this application
-specifically for you.
-
-Swipe to read the guide.
-
-
-
-
-
-
-
- Choose a master password.
-
-The first thing you'll do is choose a new master password.
-
-This password is the basis of all your
-other passwords. It either generates
-or securely encrypts them.
-
-This is the only password
-you will need to remember.
-Take your time and think of a good one.
-Don't reuse an old password.
-
-
-
-
-
-
-
- Enter your site's name.
-
-Once you're in, you can get the password
-for anything, just by entering its name
-in the search box.
-
-You can name sites, email addresses,
-but also real things like bike locks,
-phone numbers for their SIM's PIN or
-your house for the home alarm system.
-
-Examples:
-apple.com, john@doe.com, office safe, ...
-
-
-
-
-
-
-
- Previously used sites.
-
-While you enter a site's name,
-previously used sites show up immediately.
-Tap one to go directly to its password.
-
-The first time you enter a certain site,
-type its name fully and tap the result
-marked with "Create a new site".
-
-To delete a site, swipe over the
-search result for it from left to right
-and tap "Delete".
-
-
-
-
-
-
-
- Your password is then shown.
-Tap it to quickly copy it.
-
-The first time you generate a password,
-don't forget to actually set it too:
-Update your site or email account's password,
-or whatever other item this password is for.
-
-Tap the password type button if you want a different kind of password.
-Some sites have strange password policies
-that may not accept the generated password.
-You can then choose a different type of password.
-Alternatively, you can save a password
-of your own choosing.
-
-
-
-
-
-
-
- Tap to the edit button to set a custom password.
-
-Stored passwords have an edit button to let you set or update the password for the site.
-
-The password counter button.
-Generated password use a counter.
-If you increment the counter by tapping its button,
-a new password will be generated.
-Do this if someone learns the site's password
-or if the site needs you to set a new one.
-Holding down will reset the counter back to 1.
-
-
-
-
-
-
-
- Be safe online. Some tips:
-Use a different password for every site.
-
-Let the application generate a password
-for your sites. You won't need to remember
-these and they aren't save anywhere,
-so cannot get lost or stolen.
-
-It's a lot of work to change the passwords
-of all your sites, but well worth it in the end!
-
-Choose a long master password.
-Make a new password, don't reuse an old.
-Whatever you do, never give your new
-master password to anyone. Ever.
-
-A good master password is at least 10 characters long.
-Absurd sentences make great password and they're
-usually much more memorable. For example:
-Pink fluffy door frame.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -1282,22 +1081,22 @@ Pink fluffy door frame.
-
+
-
+
-
+
-
+
@@ -1456,7 +1255,7 @@ Pink fluffy door frame.
-
+
+
+
+
+
@@ -1680,6 +1483,7 @@ You could use the word wall for inspiration in finding a memorable master passw
+
@@ -1689,8 +1493,79 @@ You could use the word wall for inspiration in finding a memorable master passw
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enabling iCloud will keep all your iPhones, iPads and Macs nicely in-sync. Any site you add on this device will automatically appear on all your others as well.
+
+Thanks to the special way Master Password works, your site passwords don't need to be sent to Apple.
+If you set a custom password, it will be encrypted before it is saved to the cloud.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1706,14 +1581,14 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
-
+
@@ -1735,22 +1610,22 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
-
+
-
+
-
+
-
+
@@ -1792,21 +1667,21 @@ You could use the word wall for inspiration in finding a memorable master passw
-
-
-
+
+
+
-
+
-
+
@@ -2132,7 +2007,7 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
@@ -2186,7 +2061,488 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The passwords created by this app are not stored anywhere but created on the spot.
+
+It is vital that you
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Cgo
+
+
+
+
+
+
+
+
+ Don't reuse an old password!
+
+
+
+
+
+
+
+
+ Don't give out your master password, no matter how close you think you are with the other person.
+
+You can make passwords for all sorts of things, like email addresses, sites or real-world objects like your bike lock: if you can name it, you can get a password for it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ All
+ Outdated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2194,20 +2550,16 @@ You could use the word wall for inspiration in finding a memorable master passw
-
-
-
-
-
-
-
+
+
+
@@ -2220,7 +2572,6 @@ You could use the word wall for inspiration in finding a memorable master passw
-
@@ -2269,8 +2620,6 @@ You could use the word wall for inspiration in finding a memorable master passw
-
-
@@ -2340,6 +2689,13 @@ You could use the word wall for inspiration in finding a memorable master passw
+
+
+
+
+
+
+
@@ -2377,9 +2733,10 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
-
+
+
\ No newline at end of file
diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
index 3be56bd0..245dbdcc 100644
--- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
+++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
@@ -16,6 +16,7 @@
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
+ 93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A28369954D147E239BA /* MPSetupViewController.m */; };
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */; };
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */; };
DA30E9CF15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */; };
@@ -750,6 +751,10 @@
DABD3C261711E2DC00CF925C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DABD3BFA1711E2DC00CF925C /* InfoPlist.strings */; };
DABD3C271711E2DC00CF925C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DABD3BFC1711E2DC00CF925C /* main.m */; };
DABD3FC717122ADD00CF925C /* libscrypt-bin-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DABD3FC617122ADD00CF925C /* libscrypt-bin-ios.a */; };
+ DABD3FCA1712446200CF925C /* cloud.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD3FC81712446200CF925C /* cloud.png */; };
+ DABD3FCB1712446200CF925C /* cloud@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD3FC91712446200CF925C /* cloud@2x.png */; };
+ DABD3FCE1714F45C00CF925C /* identity.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD3FCC1714F45B00CF925C /* identity.png */; };
+ DABD3FCF1714F45C00CF925C /* identity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD3FCD1714F45B00CF925C /* identity@2x.png */; };
DAC6325E1486805C0075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DAC6326D148680650075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
@@ -938,6 +943,41 @@
remoteGlobalIDString = DA5BFA43147E415C00F98B1E;
remoteInfo = MasterPassword;
};
+ DA5A09D21714FA83005284AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = scryptenc;
+ };
+ DA5A09D41714FA83005284AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = A0511C5A127770FD00DE46C4;
+ remoteInfo = scryptcrypto;
+ };
+ DA5A09D61714FA83005284AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = DA67FE5D14E4834300DB7CC9;
+ remoteInfo = util;
+ };
+ DA5A09D81714FA83005284AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = DABD3E841711E7D600CF925C;
+ remoteInfo = "scrypt-bin-ios";
+ };
+ DA5A09DA1714FA83005284AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = DABD3E9D1711E7E000CF925C;
+ remoteInfo = "scrypt-bin-osx";
+ };
DAC63283148681200075AEA5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DA5BFA3B147E415C00F98B1E /* Project object */;
@@ -974,6 +1014,8 @@
93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = ""; };
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = ""; };
+ 93D39730673227EFF6DEFF19 /* MPSetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSetupViewController.h; sourceTree = ""; };
+ 93D39A28369954D147E239BA /* MPSetupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSetupViewController.m; sourceTree = ""; };
93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Indexing.m"; sourceTree = ""; };
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = ""; };
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
@@ -1735,7 +1777,11 @@
DABD3BF91711E2DC00CF925C /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; };
DABD3BFB1711E2DC00CF925C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
DABD3BFC1711E2DC00CF925C /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
- DABD3FC617122ADD00CF925C /* libscrypt-bin-ios.a */ = {isa = PBXFileReference; lastKnownFileType = file; name = "libscrypt-bin-ios.a"; path = "../../../External/Pearl/External/iOSPorts/ports/security/scrypt/build/Release-iphoneos/libscrypt-bin-ios.a"; sourceTree = ""; };
+ DABD3FC617122ADD00CF925C /* libscrypt-bin-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libscrypt-bin-ios.a"; path = "../../../External/Pearl/External/iOSPorts/ports/security/scrypt/build/Release-iphoneos/libscrypt-bin-ios.a"; sourceTree = ""; };
+ DABD3FC81712446200CF925C /* cloud.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud.png; sourceTree = ""; };
+ DABD3FC91712446200CF925C /* cloud@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cloud@2x.png"; sourceTree = ""; };
+ DABD3FCC1714F45B00CF925C /* identity.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = identity.png; sourceTree = ""; };
+ DABD3FCD1714F45B00CF925C /* identity@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "identity@2x.png"; sourceTree = ""; };
DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libuicolor-utilities.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DAC6326C148680650075AEA5 /* libjrswizzle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjrswizzle.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
@@ -2088,6 +2134,18 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ DA5A09C91714FA83005284AB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ DA5A09D31714FA83005284AB /* libscryptenc.a */,
+ DA5A09D51714FA83005284AB /* libscryptcrypto.a */,
+ DA5A09D71714FA83005284AB /* libutil.a */,
+ DA5A09D91714FA83005284AB /* libscrypt-bin-ios.a */,
+ DA5A09DB1714FA83005284AB /* libscrypt-bin-osx.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
DA5BFA39147E415C00F98B1E = {
isa = PBXGroup;
children = (
@@ -2166,8 +2224,12 @@
DABD38751711E29700CF925C /* Tooltips */,
DABD38C41711E29700CF925C /* book.png */,
DABD38C51711E29700CF925C /* book@2x.png */,
+ DABD3FC81712446200CF925C /* cloud.png */,
+ DABD3FC91712446200CF925C /* cloud@2x.png */,
DABD38C61711E29700CF925C /* help.html */,
DABD38C71711E29700CF925C /* iTunesArtwork.png */,
+ DABD3FCC1714F45B00CF925C /* identity.png */,
+ DABD3FCD1714F45B00CF925C /* identity@2x.png */,
DABD38C81711E29700CF925C /* jquery-1.6.1.min.js */,
DABD38C91711E29700CF925C /* keypad.png */,
DABD38CA1711E29700CF925C /* logo-bare.png */,
@@ -2944,6 +3006,8 @@
DABD3BF91711E2DC00CF925C /* Settings.bundle */,
DABD3BFA1711E2DC00CF925C /* InfoPlist.strings */,
DABD3BFC1711E2DC00CF925C /* main.m */,
+ 93D39A28369954D147E239BA /* MPSetupViewController.m */,
+ 93D39730673227EFF6DEFF19 /* MPSetupViewController.h */,
);
path = iOS;
sourceTree = "";
@@ -3769,6 +3833,12 @@
mainGroup = DA5BFA39147E415C00F98B1E;
productRefGroup = DA5BFA45147E415C00F98B1E /* Products */;
projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = DA5A09C91714FA83005284AB /* Products */;
+ ProjectRef = DACA29C01705E313002C6C22 /* scrypt.xcodeproj */;
+ },
+ );
projectRoot = "";
targets = (
DA5BFA43147E415C00F98B1E /* MasterPassword */,
@@ -3785,6 +3855,44 @@
};
/* End PBXProject section */
+/* Begin PBXReferenceProxy section */
+ DA5A09D31714FA83005284AB /* libscryptenc.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libscryptenc.a;
+ remoteRef = DA5A09D21714FA83005284AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ DA5A09D51714FA83005284AB /* libscryptcrypto.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libscryptcrypto.a;
+ remoteRef = DA5A09D41714FA83005284AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ DA5A09D71714FA83005284AB /* libutil.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libutil.a;
+ remoteRef = DA5A09D61714FA83005284AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ DA5A09D91714FA83005284AB /* libscrypt-bin-ios.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libscrypt-bin-ios.a";
+ remoteRef = DA5A09D81714FA83005284AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ DA5A09DB1714FA83005284AB /* libscrypt-bin-osx.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libscrypt-bin-osx.a";
+ remoteRef = DA5A09DA1714FA83005284AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
/* Begin PBXResourcesBuildPhase section */
DA3EF17615A47744003ABF4E /* Resources */ = {
isa = PBXResourcesBuildPhase;
@@ -4476,6 +4584,10 @@
DABD3C241711E2DC00CF925C /* MasterPassword.entitlements in Resources */,
DABD3C251711E2DC00CF925C /* Settings.bundle in Resources */,
DABD3C261711E2DC00CF925C /* InfoPlist.strings in Resources */,
+ DABD3FCA1712446200CF925C /* cloud.png in Resources */,
+ DABD3FCB1712446200CF925C /* cloud@2x.png in Resources */,
+ DABD3FCE1714F45C00CF925C /* identity.png in Resources */,
+ DABD3FCF1714F45C00CF925C /* identity@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4612,6 +4724,7 @@
DABD3C201711E2DC00CF925C /* MPUnlockViewController.m in Sources */,
DABD3C211711E2DC00CF925C /* MPiOSConfig.m in Sources */,
DABD3C271711E2DC00CF925C /* main.m in Sources */,
+ 93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5459,7 +5572,7 @@
DABD3BD31711E2DC00CF925C /* MasterPassword 3.xcdatamodel */,
DABD3BD41711E2DC00CF925C /* MasterPassword 4.xcdatamodel */,
);
- currentVersion = DABD3BD11711E2DC00CF925C /* MasterPassword 1.xcdatamodel */;
+ currentVersion = DABD3BD41711E2DC00CF925C /* MasterPassword 4.xcdatamodel */;
path = MasterPassword.xcdatamodeld;
sourceTree = "";
versionGroupType = wrapper.xcdatamodel;
diff --git a/MasterPassword/Resources/Media/cloud.png b/MasterPassword/Resources/Media/cloud.png
new file mode 100644
index 00000000..df92c7fc
Binary files /dev/null and b/MasterPassword/Resources/Media/cloud.png differ
diff --git a/MasterPassword/Resources/Media/cloud@2x.png b/MasterPassword/Resources/Media/cloud@2x.png
new file mode 100644
index 00000000..c8ec3f50
Binary files /dev/null and b/MasterPassword/Resources/Media/cloud@2x.png differ
diff --git a/MasterPassword/Resources/Media/identity.png b/MasterPassword/Resources/Media/identity.png
new file mode 100644
index 00000000..be3c8bfa
Binary files /dev/null and b/MasterPassword/Resources/Media/identity.png differ
diff --git a/MasterPassword/Resources/Media/identity@2x.png b/MasterPassword/Resources/Media/identity@2x.png
new file mode 100644
index 00000000..48a8e81d
Binary files /dev/null and b/MasterPassword/Resources/Media/identity@2x.png differ
diff --git a/MasterPassword/Resources/Media/lock.png b/MasterPassword/Resources/Media/lock.png
new file mode 100644
index 00000000..5dee9649
Binary files /dev/null and b/MasterPassword/Resources/Media/lock.png differ
diff --git a/MasterPassword/Resources/Media/lock@2x.png b/MasterPassword/Resources/Media/lock@2x.png
new file mode 100644
index 00000000..d34f8a22
Binary files /dev/null and b/MasterPassword/Resources/Media/lock@2x.png differ
diff --git a/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Preview.pdf b/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Preview.pdf
new file mode 100644
index 00000000..c9c1360c
Binary files /dev/null and b/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Preview.pdf differ
diff --git a/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Thumbnail.jpg b/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Thumbnail.jpg
new file mode 100644
index 00000000..0e1da73d
Binary files /dev/null and b/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Thumbnail.jpg differ
diff --git a/MasterPassword/Resources/Raw/Large Icons.vdesigner/VectorDesigner b/MasterPassword/Resources/Raw/Large Icons.vdesigner/VectorDesigner
new file mode 100644
index 00000000..39f58601
Binary files /dev/null and b/MasterPassword/Resources/Raw/Large Icons.vdesigner/VectorDesigner differ