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. - - - - - - - - - - - - - - - - - - - - - - - - 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. - + - + @@ -1662,7 +1461,11 @@ You could use the word wall for inspiration in finding a memorable master passw + + + + @@ -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 - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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