diff --git a/External/Pearl b/External/Pearl index 0e9484b6..daa260b3 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit 0e9484b6512150fbbfffdddcdec62f8e9a741254 +Subproject commit daa260b3ecaca266ffcfa597e9350900dda6cc56 diff --git a/External/iOS/Crashlytics.framework/Versions/A/Crashlytics b/External/iOS/Crashlytics.framework/Versions/A/Crashlytics index f5c38d4f..f286bd15 100644 Binary files a/External/iOS/Crashlytics.framework/Versions/A/Crashlytics and b/External/iOS/Crashlytics.framework/Versions/A/Crashlytics differ diff --git a/External/iOS/Crashlytics.framework/Versions/A/Resources/Info.plist b/External/iOS/Crashlytics.framework/Versions/A/Resources/Info.plist index 4971ea17..608be399 100644 --- a/External/iOS/Crashlytics.framework/Versions/A/Resources/Info.plist +++ b/External/iOS/Crashlytics.framework/Versions/A/Resources/Info.plist @@ -15,13 +15,13 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.1.9 + 2.2.0 CFBundleSupportedPlatforms iPhoneOS CFBundleVersion - 31 + 33 DTPlatformName iphoneos MinimumOSVersion diff --git a/External/iOS/Crashlytics.framework/run b/External/iOS/Crashlytics.framework/run index 599d7616..d3ddf05f 100755 Binary files a/External/iOS/Crashlytics.framework/run and b/External/iOS/Crashlytics.framework/run differ diff --git a/External/iOS/Crashlytics.framework/submit b/External/iOS/Crashlytics.framework/submit new file mode 100755 index 00000000..2a5784eb Binary files /dev/null and b/External/iOS/Crashlytics.framework/submit differ diff --git a/MasterPassword/ObjC/MPAppDelegate_Key.m b/MasterPassword/ObjC/MPAppDelegate_Key.m index 9aa55c10..f8fe462d 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Key.m +++ b/MasterPassword/ObjC/MPAppDelegate_Key.m @@ -107,13 +107,11 @@ static NSDictionary *keyQuery(MPUserEntity *user) { } // Method 3: Check the given master password string. - if (!tryKey) { - if ([password length]) if ((tryKey = [MPAlgorithmDefault keyForPassword:password - ofUserNamed:user.name])) if (![user.keyID isEqual:tryKey.keyID]) { - inf( @"Key derived from password doesn't match keyID for: %@", user.userID ); + if (!tryKey && [password length] && (tryKey = [MPAlgorithmDefault keyForPassword:password ofUserNamed:user.name]) && + ![user.keyID isEqual:tryKey.keyID]) { + inf( @"Key derived from password doesn't match keyID for: %@", user.userID ); - tryKey = nil; - } + tryKey = nil; } // No more methods left, fail if key still not known. diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m index 0f9cedb3..654ba6ee 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeCell.m @@ -30,6 +30,8 @@ + (instancetype)dequeueCellWithType:(MPElementType)type fromCollectionView:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)indexPath { + NSAssert(type != 0 && type != (MPElementType)NSNotFound, @"Cannot dequeue a password cell without a type."); + NSString *reuseIdentifier; if (type & MPElementTypeClassGenerated) reuseIdentifier = NSStringFromClass( [MPPasswordLargeGeneratedCell class] ); @@ -163,6 +165,13 @@ return YES; } +- (void)textFieldDidBeginEditing:(UITextField *)textField { + + UICollectionView *collectionView = [UICollectionView findAsSuperviewOf:self]; + [collectionView scrollToItemAtIndexPath:[collectionView indexPathForCell:self] + atScrollPosition:UICollectionViewScrollPositionTop animated:YES]; +} + - (void)textFieldDidEndEditing:(UITextField *)textField { if (textField == self.contentField) { diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.h b/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.h index 03add62f..93de5523 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.h +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.h @@ -21,4 +21,5 @@ @interface MPPasswordLargeDeleteCell : MPPasswordLargeCell ++ (MPPasswordLargeCell *)dequeueCellFromCollectionView:(UICollectionView *)view atIndexPath:(NSIndexPath *)path; @end diff --git a/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.m b/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.m index a422f54a..05db27a5 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordLargeDeleteCell.m @@ -1,12 +1,12 @@ /** - * 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 - */ +* 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 +*/ // // MPPasswordLargeDeleteCell.h @@ -22,6 +22,15 @@ #pragma mark - Lifecycle ++ (MPPasswordLargeCell *)dequeueCellFromCollectionView:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)indexPath { + + MPPasswordLargeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass( [self class] ) + forIndexPath:indexPath]; + cell.type = (MPElementType)NSNotFound; + + return cell; +} + - (MPElementEntity *)saveContentTypeWithElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context { return element; diff --git a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m index c316d21d..a567ad63 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m @@ -87,30 +87,32 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { if (!self.algorithm) - dbg_return_tr( 0, @, @(section) ); + return 0; if (self.transientSite) - dbg_return_tr( [[self.algorithm allTypes] count], @, @(section) ); + return [[self.algorithm allTypes] count]; - dbg_return_tr( [[self.algorithm allTypes] count] + 1 /* Delete */, @, @(section) ); + return [[self.algorithm allTypes] count] + 1 /* Delete */; } - (MPPasswordLargeCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { MPPasswordLargeCell *cell; if (indexPath.item == 0) - cell = [MPPasswordLargeDeleteCell dequeueCellWithType:(MPElementType)NSNotFound fromCollectionView:collectionView - atIndexPath:indexPath]; + cell = [MPPasswordLargeDeleteCell dequeueCellFromCollectionView:collectionView atIndexPath:indexPath]; else cell = [MPPasswordLargeCell dequeueCellWithType:[self typeForContentIndexPath:indexPath] fromCollectionView:collectionView atIndexPath:indexPath]; + [cell prepareForReuse]; + if (self.transientSite) [cell updateWithTransientSite:self.transientSite]; else [cell updateWithElement:self.mainElement]; + dbg( @"cell %d, contentFieldMode: %d", indexPath.item, cell.contentFieldMode ); - dbg_return( cell, indexPath ); + return cell; } #pragma mark - UICollectionViewDelegateFlowLayout diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.m b/MasterPassword/ObjC/iOS/MPUsersViewController.m index 9e0a9d3a..eae97458 100644 --- a/MasterPassword/ObjC/iOS/MPUsersViewController.m +++ b/MasterPassword/ObjC/iOS/MPUsersViewController.m @@ -129,7 +129,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { break; } case MPActiveUserStateLogin: { - [self.entryField endEditing:YES]; + self.entryField.enabled = NO; [self selectedAvatar].spinnerActive = YES; [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { BOOL signedIn = NO, isNew = NO; @@ -140,6 +140,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.entryField.text = @""; + self.entryField.enabled = YES; [self selectedAvatar].spinnerActive = NO; if (!signedIn) { @@ -189,7 +190,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { return NO; } - [self.entryField endEditing:YES]; + self.entryField.enabled = NO; MPAvatarCell *avatarCell = [self selectedAvatar]; avatarCell.spinnerActive = YES; if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { @@ -204,6 +205,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context usingMasterPassword:masterPassword]; PearlMainQueue( ^{ self.entryField.text = @""; + self.entryField.enabled = YES; [self selectedAvatar].spinnerActive = NO; if (!signedIn) { @@ -315,15 +317,29 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { } BOOL isNew = NO; - MPUserEntity *user = [self userForIndexPath:indexPath inContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady] - isNew:&isNew]; + NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady]; + MPUserEntity *mainUser = [self userForIndexPath:indexPath inContext:mainContext isNew:&isNew]; if (isNew) self.activeUserState = MPActiveUserStateUserName; - else if (!user.keyID) + else if (!mainUser.keyID) self.activeUserState = MPActiveUserStateMasterPasswordChoice; - else + else { self.activeUserState = MPActiveUserStateLogin; + + self.entryField.enabled = NO; + [self selectedAvatar].spinnerActive = YES; + BOOL signedIn = NO; + if (!isNew && mainUser) + signedIn = [[MPiOSAppDelegate get] signInAsUser:mainUser saveInContext:mainContext usingMasterPassword:nil]; + + self.entryField.text = @""; + self.entryField.enabled = YES; + [self selectedAvatar].spinnerActive = NO; + + if (!signedIn) + [self.entryField becomeFirstResponder]; + } } } diff --git a/MasterPassword/ObjC/iOS/Storyboard.storyboard b/MasterPassword/ObjC/iOS/Storyboard.storyboard index 301a77d6..63b4c275 100644 --- a/MasterPassword/ObjC/iOS/Storyboard.storyboard +++ b/MasterPassword/ObjC/iOS/Storyboard.storyboard @@ -16,19 +16,19 @@ - + - + - + - + @@ -39,7 +39,7 @@ - + @@ -110,11 +110,11 @@ - + - + @@ -123,7 +123,7 @@ - + - + -