diff --git a/platform-darwin/Source/MPAppDelegate_InApp.m b/platform-darwin/Source/MPAppDelegate_InApp.m index 169a8d9b..ca84e18e 100644 --- a/platform-darwin/Source/MPAppDelegate_InApp.m +++ b/platform-darwin/Source/MPAppDelegate_InApp.m @@ -161,13 +161,14 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve MPError( error, @"StoreKit request (%@) failed.", request ); #if TARGET_OS_IPHONE - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Purchase Failed" message: - strf( @"%@\n\n%@", error.localizedDescription, - @"Ensure you are online and try logging out and back into iTunes from your device's Settings." ) - preferredStyle:UIAlertControllerStyleAlert]; - [controller addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]]; - [self.navigationController presentViewController:controller animated:YES completion:nil]; -#else + PearlMainQueue( ^{ + UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Purchase Failed" message: + strf( @"%@\n\n%@", error.localizedDescription, + @"Ensure you are online and try logging out and back into iTunes from your device's Settings." ) + preferredStyle:UIAlertControllerStyleAlert]; + [controller addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]]; + [self.navigationController presentViewController:controller animated:YES completion:nil]; + } ); #endif } diff --git a/platform-darwin/Source/MPAppDelegate_Key.m b/platform-darwin/Source/MPAppDelegate_Key.m index 244c3e93..cc586480 100644 --- a/platform-darwin/Source/MPAppDelegate_Key.m +++ b/platform-darwin/Source/MPAppDelegate_Key.m @@ -248,8 +248,7 @@ MPKey *recoverKey = newKey; #ifdef PEARL_UIKIT - PearlOverlay *activityOverlay = [PearlOverlay showProgressOverlayWithTitle:PearlString( @"Migrating %ld sites...", - (long)[user.sites count] )]; + PearlOverlay *activityOverlay = [PearlOverlay showProgressOverlayWithTitle:strf( @"Migrating %ld sites...", (long)[user.sites count] )]; #endif for (MPSiteEntity *site in user.sites) { @@ -261,19 +260,21 @@ #ifdef PEARL_UIKIT masterPassword = PearlAwait( ^(void (^setResult)(id)) { - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Enter Old Master Password" message: - PearlString( @"Your old master password is required to migrate the stored password for %@", site.name ) - preferredStyle:UIAlertControllerStyleAlert]; - [controller addTextFieldWithConfigurationHandler:nil]; - [controller addAction:[UIAlertAction actionWithTitle:@"Migrate" style:UIAlertActionStyleDefault handler: - ^(UIAlertAction *_Nonnull action) { - setResult( controller.textFields.firstObject.text ); - }]]; - [controller addAction:[UIAlertAction actionWithTitle:@"Don't Migrate" style:UIAlertActionStyleCancel handler: - ^(UIAlertAction *_Nonnull action) { - setResult( nil ); - }]]; - [self.navigationController presentViewController:controller animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Enter Old Master Password" message: + strf( @"Your old master password is required to migrate the stored password for %@", site.name ) + preferredStyle:UIAlertControllerStyleAlert]; + [controller addTextFieldWithConfigurationHandler:nil]; + [controller addAction:[UIAlertAction actionWithTitle:@"Migrate" style:UIAlertActionStyleDefault handler: + ^(UIAlertAction *_Nonnull action) { + setResult( controller.textFields.firstObject.text ); + }]]; + [controller addAction:[UIAlertAction actionWithTitle:@"Don't Migrate" style:UIAlertActionStyleCancel handler: + ^(UIAlertAction *_Nonnull action) { + setResult( nil ); + }]]; + [self.navigationController presentViewController:controller animated:YES completion:nil]; + } ); } ); #endif if (!masterPassword) diff --git a/platform-darwin/Source/MPAppDelegate_Store.m b/platform-darwin/Source/MPAppDelegate_Store.m index c01a29cc..e263dfde 100644 --- a/platform-darwin/Source/MPAppDelegate_Store.m +++ b/platform-darwin/Source/MPAppDelegate_Store.m @@ -548,11 +548,8 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted ); do { if ([MPAppDelegate_Shared managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) { - NSError *error = [self importSites:importData askImportPassword:importPassword askUserPassword:userPassword - saveInContext:context]; - PearlMainQueue( ^{ - resultBlock( error ); - } ); + resultBlock( [self importSites:importData askImportPassword:importPassword askUserPassword:userPassword + saveInContext:context] ); }]) break; usleep( (useconds_t)(USEC_PER_SEC * 0.2) ); diff --git a/platform-darwin/Source/iOS/MPPreferencesViewController.m b/platform-darwin/Source/iOS/MPPreferencesViewController.m index fa800617..a77706d8 100644 --- a/platform-darwin/Source/iOS/MPPreferencesViewController.m +++ b/platform-darwin/Source/iOS/MPPreferencesViewController.m @@ -113,7 +113,7 @@ } if (cell == self.checkInconsistencies) - [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { + [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) { if ([[MPiOSAppDelegate get] findAndFixInconsistenciesSaveInContext:context] == MPFixableResultNoProblems) { UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"No Inconsistencies" message: @"No inconsistencies were detected in your sites." @@ -215,7 +215,7 @@ - (IBAction)securityButton:(id)sender { [[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender: - [NSURL URLWithString:@"https://masterpassword.app/security.html"]]; + [NSURL URLWithString:@"https://masterpassword.app/masterpassword-algorithm.pdf"]]; } - (IBAction)sourceButton:(id)sender { diff --git a/platform-darwin/Source/iOS/MPStoreViewController.m b/platform-darwin/Source/iOS/MPStoreViewController.m index 4c1b3cc8..c3eb02f2 100644 --- a/platform-darwin/Source/iOS/MPStoreViewController.m +++ b/platform-darwin/Source/iOS/MPStoreViewController.m @@ -40,7 +40,7 @@ PearlEnum( MPDevelopmentFuelConsumption, NSMutableString *features = [NSMutableString string]; NSArray *storeVersions = @[ @"Generated Usernames\nSecurity Question Answers", - @"TouchID Support" + @"Biometrics Support", ]; NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"]; for (; storeVersion < [storeVersions count]; ++storeVersion) diff --git a/platform-darwin/Source/iOS/MPUsersViewController.m b/platform-darwin/Source/iOS/MPUsersViewController.m index e504e423..e8968ffa 100644 --- a/platform-darwin/Source/iOS/MPUsersViewController.m +++ b/platform-darwin/Source/iOS/MPUsersViewController.m @@ -431,22 +431,22 @@ referenceSizeForFooterInSection:(NSInteger)section { NSManagedObjectID *userID = user.permanentObjectID; UIAlertController *controller = [UIAlertController alertControllerWithTitle:user.name message:nil preferredStyle:UIAlertControllerStyleActionSheet]; [controller addAction:[UIAlertAction actionWithTitle:@"Delete User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Deleting User" message: - @"The user and its sites will be deleted." preferredStyle:UIAlertControllerStyleAlert]; - [controller addAction:[UIAlertAction actionWithTitle:@"Delete User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + UIAlertController *controller_ = [UIAlertController alertControllerWithTitle:@"Deleting User" message: + @"The user and its sites will be deleted." preferredStyle:UIAlertControllerStyleAlert]; + [controller_ addAction:[UIAlertAction actionWithTitle:@"Delete User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { [self deleteUser:userID]; }]]; - [controller addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; - [self presentViewController:controller animated:YES completion:nil]; + [controller_ addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:controller_ animated:YES completion:nil]; }]]; [controller addAction:[UIAlertAction actionWithTitle:@"Reset Password" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Resetting User" message: - @"The user's master password will be reset." preferredStyle:UIAlertControllerStyleAlert]; - [controller addAction:[UIAlertAction actionWithTitle:@"Reset User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + UIAlertController *controller_ = [UIAlertController alertControllerWithTitle:@"Resetting User" message: + @"The user's master password will be reset." preferredStyle:UIAlertControllerStyleAlert]; + [controller_ addAction:[UIAlertAction actionWithTitle:@"Reset User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { [self resetUser:userID avatar:avatarCell]; }]]; - [controller addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; - [self presentViewController:controller animated:YES completion:nil]; + [controller_ addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:controller_ animated:YES completion:nil]; }]]; [controller addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:controller animated:YES completion:nil]; diff --git a/platform-darwin/Source/iOS/MPiOSAppDelegate.m b/platform-darwin/Source/iOS/MPiOSAppDelegate.m index 9d948016..3b1057b8 100644 --- a/platform-darwin/Source/iOS/MPiOSAppDelegate.m +++ b/platform-darwin/Source/iOS/MPiOSAppDelegate.m @@ -182,7 +182,8 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { @try { inf( @"Started up with device identifier: %@", [PearlKeyChain deviceIdentifier] ); - PearlAddNotificationObserver( MPFoundInconsistenciesNotification, nil, nil, ^(id self, NSNotification *note) { + PearlAddNotificationObserver( + MPFoundInconsistenciesNotification, nil, [NSOperationQueue mainQueue], ^(id self, NSNotification *note) { switch ((MPFixableResult)[note.userInfo[MPInconsistenciesFixResultUserKey] unsignedIntegerValue]) { case MPFixableResultNoProblems: @@ -244,22 +245,26 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { MPError( error, @"While reading imported sites from %@.", url ); if (!importedSitesData) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message: - strf( @"Master Password couldn't read the import sites.\n\n%@", - (id)[error localizedDescription]?: error ) - preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; - [self.navigationController presentViewController:alert animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message: + strf( @"Master Password couldn't read the import sites.\n\n%@", + (id)[error localizedDescription]?: error ) + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + } ); return; } NSString *importedSitesString = [[NSString alloc] initWithData:importedSitesData encoding:NSUTF8StringEncoding]; if (!importedSitesString) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message: - @"Master Password couldn't understand the import file." - preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; - [self.navigationController presentViewController:alert animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message: + @"Master Password couldn't understand the import file." + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + } ); return; } @@ -281,44 +286,50 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { PearlOverlay *activityOverlay = [PearlOverlay showProgressOverlayWithTitle:@"Importing"]; [self importSites:importData askImportPassword:^NSString *(NSString *userName) { return PearlAwait( ^(void (^setResult)(id)) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf( @"Importing Sites For\n%@", userName ) message: - @"Enter the master password used to create this export file." - preferredStyle:UIAlertControllerStyleAlert]; - [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { - textField.secureTextEntry = YES; - }]; - [alert addAction:[UIAlertAction actionWithTitle:@"Import" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - setResult( alert.textFields.firstObject.text ); - }]]; - [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { - setResult( nil ); - }]]; - [self.navigationController presentViewController:alert animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf( @"Importing Sites For\n%@", userName ) message: + @"Enter the master password used to create this export file." + preferredStyle:UIAlertControllerStyleAlert]; + [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.secureTextEntry = YES; + }]; + [alert addAction:[UIAlertAction actionWithTitle:@"Import" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + setResult( alert.textFields.firstObject.text ); + }]]; + [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { + setResult( nil ); + }]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + } ); } ); } askUserPassword:^NSString *(NSString *userName) { return PearlAwait( (id)^(void (^setResult)(id)) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf( @"Master Password For\n%@", userName ) message: - @"Enter the current master password for this user." - preferredStyle:UIAlertControllerStyleAlert]; - [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { - textField.secureTextEntry = YES; - }]; - [alert addAction:[UIAlertAction actionWithTitle:@"Import" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - setResult( alert.textFields.firstObject.text ); - }]]; - [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { - setResult( nil ); - }]]; - [self.navigationController presentViewController:alert animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf( @"Master Password For\n%@", userName ) message: + @"Enter the current master password for this user." + preferredStyle:UIAlertControllerStyleAlert]; + [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.secureTextEntry = YES; + }]; + [alert addAction:[UIAlertAction actionWithTitle:@"Import" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + setResult( alert.textFields.firstObject.text ); + }]]; + [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { + setResult( nil ); + }]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + } ); } ); } result:^(NSError *error) { [activityOverlay cancelOverlayAnimated:YES]; if (error && !(error.domain == NSCocoaErrorDomain && error.code == NSUserCancelledError)) { - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Error" message:[error localizedDescription] - preferredStyle:UIAlertControllerStyleAlert]; - [controller addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; - [self.navigationController presentViewController:controller animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Error" message:[error localizedDescription] + preferredStyle:UIAlertControllerStyleAlert]; + [controller addAction:[UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleCancel handler:nil]]; + [self.navigationController presentViewController:controller animated:YES completion:nil]; + } ); } }]; } @@ -341,16 +352,18 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { NSString *importData = [UIPasteboard generalPasteboard].string; MPMarshalledFile *importFile = mpw_marshal_read( NULL, importData.UTF8String ); if (importFile && importFile->error.type == MPMarshalSuccess && importFile->info->format != MPMarshalFormatNone) { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Import Sites?" message: - @"We've detected Master Password import sites on your pasteboard, would you like to import them?" - preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Import Sites" style:UIAlertActionStyleDefault handler: - ^(UIAlertAction *action) { - [self importSites:importData]; - [UIPasteboard generalPasteboard].string = @""; - }]]; - [alert addAction:[UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleCancel handler:nil]]; - [self.navigationController presentViewController:alert animated:YES completion:nil]; + PearlMainQueue( ^{ + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Import Sites?" message: + @"We've detected Master Password import sites on your pasteboard, would you like to import them?" + preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Import Sites" style:UIAlertActionStyleDefault handler: + ^(UIAlertAction *action) { + [self importSites:importData]; + [UIPasteboard generalPasteboard].string = @""; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleCancel handler:nil]]; + [self.navigationController presentViewController:alert animated:YES completion:nil]; + } ); } mpw_marshal_file_free( &importFile ); } ); @@ -422,7 +435,7 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Feedback" message: @"Have a question, comment, issue or just saying thanks?\n\n" @"We'd love to hear what you think!\n" - @"masterpassword@lyndir.com" + @"help@masterpassword.app" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:nil]]; [self.navigationController presentViewController:alert animated:YES completion:nil]; @@ -452,7 +465,7 @@ void mpw_log_sink_pearl(const MPLogEvent *record) { if (logs && ([[MPConfig get].sendInfo boolValue] || [[MPiOSConfig get].traceMode boolValue])) logLevel = PearlLogLevelDebug; - [[[PearlEMail alloc] initForEMailTo:@"Master Password Development " + [[[PearlEMail alloc] initForEMailTo:@"Master Password Development [auto] CFBundleVersion [auto] - LSApplicationQueriesSchemes - - volto - LSRequiresIPhoneOS NSHumanReadableCopyright diff --git a/platform-darwin/Source/iOS/Storyboard.storyboard b/platform-darwin/Source/iOS/Storyboard.storyboard index 58128f88..ddba2297 100644 --- a/platform-darwin/Source/iOS/Storyboard.storyboard +++ b/platform-darwin/Source/iOS/Storyboard.storyboard @@ -69,7 +69,7 @@ - + @@ -898,15 +898,15 @@ -