Style login name, add login generated gear, improve logic for when to show login name.
This commit is contained in:
parent
907d2a8ca6
commit
0a1f215a1a
2
platform-darwin/External/Pearl
vendored
2
platform-darwin/External/Pearl
vendored
@ -1 +1 @@
|
||||
Subproject commit 6f3efd7abd80019ea1945f3a2cc5a6f4bbb3ad67
|
||||
Subproject commit eee65e95220fdc1c775dbecdc795d64da1dad047
|
@ -478,10 +478,12 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
else
|
||||
algorithm = site.algorithm;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
resultBlock( loginName || !loginGenerated? loginName:
|
||||
[algorithm generateLoginForSiteNamed:name usingKey:siteKey] );
|
||||
} );
|
||||
if (!loginGenerated || [loginName length])
|
||||
resultBlock( loginName );
|
||||
else
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [algorithm generateLoginForSiteNamed:name usingKey:siteKey] );
|
||||
} );
|
||||
}
|
||||
|
||||
- (void)resolvePasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey result:(void ( ^ )(NSString *result))resultBlock {
|
||||
@ -513,9 +515,8 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
else
|
||||
algorithm = site.algorithm;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSString *result = [algorithm generatePasswordForSiteNamed:name ofType:type withCounter:counter usingKey:siteKey];
|
||||
resultBlock( result );
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [algorithm generatePasswordForSiteNamed:name ofType:type withCounter:counter usingKey:siteKey] );
|
||||
} );
|
||||
break;
|
||||
}
|
||||
@ -529,9 +530,8 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
|
||||
NSData *encryptedContent = ((MPStoredSiteEntity *)site).contentObject;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSString *result = [self decryptContent:encryptedContent usingKey:siteKey];
|
||||
resultBlock( result );
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [self decryptContent:encryptedContent usingKey:siteKey] );
|
||||
} );
|
||||
break;
|
||||
}
|
||||
@ -543,9 +543,8 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
NSDictionary *siteQuery = [self queryForDevicePrivateSiteNamed:site.name];
|
||||
NSData *encryptedContent = [PearlKeyChain dataOfItemForQuery:siteQuery];
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSString *result = [self decryptContent:encryptedContent usingKey:siteKey];
|
||||
resultBlock( result );
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [self decryptContent:encryptedContent usingKey:siteKey] );
|
||||
} );
|
||||
break;
|
||||
}
|
||||
@ -564,9 +563,8 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
else
|
||||
algorithm = site.algorithm;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSString *result = [algorithm generateAnswerForSiteNamed:name onQuestion:nil usingKey:siteKey];
|
||||
resultBlock( result );
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [algorithm generateAnswerForSiteNamed:name onQuestion:nil usingKey:siteKey] );
|
||||
} );
|
||||
}
|
||||
|
||||
@ -585,9 +583,8 @@ NSOperationQueue *_mpwQueue = nil;
|
||||
else if ([[MPAppDelegate_Shared get] isFeatureUnlocked:MPProductGenerateAnswers])
|
||||
algorithm = question.site.algorithm;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSString *result = [algorithm generateAnswerForSiteNamed:name onQuestion:keyword usingKey:siteKey];
|
||||
resultBlock( result );
|
||||
PearlNotMainQueue( ^{
|
||||
resultBlock( [algorithm generateAnswerForSiteNamed:name onQuestion:keyword usingKey:siteKey] );
|
||||
} );
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
@property(nonatomic, strong) IBOutlet UITextField *passwordField;
|
||||
@property(nonatomic, strong) IBOutlet UIView *loginNameContainer;
|
||||
@property(nonatomic, strong) IBOutlet UITextField *loginNameField;
|
||||
@property(nonatomic, strong) IBOutlet UILabel *loginNameGenerated;
|
||||
@property(nonatomic, strong) IBOutlet UILabel *strengthLabel;
|
||||
@property(nonatomic, strong) IBOutlet UILabel *counterLabel;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *counterButton;
|
||||
@ -199,7 +200,7 @@
|
||||
atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
|
||||
|
||||
if (textField == self.loginNameField)
|
||||
self.loginNameButton.titleLabel.alpha = [self.loginNameField.text length] || self.loginNameField.enabled? 0: 1;
|
||||
self.loginNameButton.hidden = [self.loginNameField.attributedText length] || self.loginNameField.enabled;
|
||||
}
|
||||
|
||||
- (IBAction)textFieldDidChange:(UITextField *)textField {
|
||||
@ -224,7 +225,7 @@
|
||||
|
||||
if (textField == self.passwordField || textField == self.loginNameField) {
|
||||
textField.enabled = NO;
|
||||
NSString *text = textField.text;
|
||||
NSString *text = [textField.attributedText string]?: textField.text;
|
||||
|
||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||
MPSiteEntity *site = [self siteInContext:context];
|
||||
@ -235,10 +236,8 @@
|
||||
if ([site.algorithm savePassword:text toSite:site usingKey:[MPiOSAppDelegate get].key])
|
||||
[PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2];
|
||||
}
|
||||
else if (textField == self.loginNameField &&
|
||||
((site.loginGenerated && ![text length]) ||
|
||||
(!site.loginGenerated && ![text isEqualToString:site.loginName]))) {
|
||||
if (site.loginGenerated || !([site.loginName isEqualToString:text] || (!text && !site.loginName))) {
|
||||
else if (textField == self.loginNameField) {
|
||||
if (![text isEqualToString:[site.algorithm resolveLoginForSite:site usingKey:[MPiOSAppDelegate get].key]]) {
|
||||
site.loginGenerated = NO;
|
||||
site.loginName = text;
|
||||
|
||||
@ -508,7 +507,6 @@
|
||||
self.answersButton.gone = ![[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateAnswers];
|
||||
BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
|
||||
self.loginNameContainer.alpha = settingsMode || mainSite.loginGenerated || [mainSite.loginName length]? 0.7f: 0;
|
||||
self.loginNameField.textColor = [UIColor colorWithHexString:mainSite.loginGenerated? @"5E636D": @"6D5E63"];
|
||||
self.modeButton.alpha = self.transientSite? 0: settingsMode? 0.5f: 0.1f;
|
||||
self.counterLabel.alpha = self.counterButton.alpha = mainSite.type & MPSiteTypeClassGenerated? 0.5f: 0;
|
||||
self.modeButton.selected = settingsMode;
|
||||
@ -520,13 +518,21 @@
|
||||
[self.passwordField resignFirstResponder];
|
||||
}
|
||||
if ([[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateLogins])
|
||||
[self.loginNameButton setTitle:@"Tap to generate username or use pencil to save one" forState:UIControlStateNormal];
|
||||
[self.loginNameButton setTitle:@"Tap here to ⚙ generate username or the pencil to type one" forState:UIControlStateNormal];
|
||||
else
|
||||
[self.loginNameButton setTitle:@"Tap the pencil to save a username" forState:UIControlStateNormal];
|
||||
[self.loginNameButton setTitle:@"Tap the pencil to type a username" forState:UIControlStateNormal];
|
||||
|
||||
// Site Name
|
||||
[self updateSiteName:mainSite];
|
||||
|
||||
// Site Counter
|
||||
if ([mainSite isKindOfClass:[MPGeneratedSiteEntity class]])
|
||||
self.counterLabel.text = strf( @"%lu", (unsigned long)((MPGeneratedSiteEntity *)mainSite).counter );
|
||||
|
||||
// Site Login Name
|
||||
self.loginNameField.enabled = self.passwordField.enabled = //
|
||||
[self.loginNameField isFirstResponder] || [self.passwordField isFirstResponder];
|
||||
|
||||
// Site Password
|
||||
self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue];
|
||||
self.passwordField.attributedPlaceholder = stra(
|
||||
@ -534,12 +540,15 @@
|
||||
mainSite.type & MPSiteTypeClassGenerated? strl( @"..." ): @"", @{
|
||||
NSForegroundColorAttributeName: [UIColor whiteColor]
|
||||
} );
|
||||
|
||||
// Calculate Fields
|
||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||
MPSiteEntity *site = [self siteInContext:context];
|
||||
MPKey *key = [MPiOSAppDelegate get].key;
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
BOOL loginGenerated = site.loginGenerated;
|
||||
NSString *password = nil, *loginName = [site resolveLoginUsingKey:key];
|
||||
MPSiteType transientType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPSiteTypeGeneratedLong;
|
||||
if (self.transientSite && transientType & MPSiteTypeClassGenerated)
|
||||
@ -559,13 +568,15 @@
|
||||
BOOL requiresExplicitMigration = site.requiresExplicitMigration;
|
||||
|
||||
PearlMainQueue( ^{
|
||||
self.loginNameField.text = loginName;
|
||||
self.passwordField.text = password;
|
||||
self.strengthLabel.text = timeToCrackString;
|
||||
self.loginNameButton.titleLabel.alpha = [loginName length] || self.loginNameField.enabled? 0: 1;
|
||||
self.loginNameGenerated.hidden = !loginGenerated;
|
||||
self.loginNameField.attributedText =
|
||||
strarm( stra( loginName?: @"", self.siteNameLabel.textAttributes ), NSParagraphStyleAttributeName, nil );
|
||||
self.loginNameButton.hidden = [loginName length] || self.loginNameField.enabled;
|
||||
|
||||
if (![password length]) {
|
||||
self.indicatorView.alpha = 1;
|
||||
self.indicatorView.hidden = NO;
|
||||
[self.indicatorView removeFromSuperview];
|
||||
[self.modeScrollView addSubview:self.indicatorView];
|
||||
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
||||
@ -575,7 +586,7 @@
|
||||
}];
|
||||
}
|
||||
else if (requiresExplicitMigration) {
|
||||
self.indicatorView.alpha = 1;
|
||||
self.indicatorView.hidden = NO;
|
||||
[self.indicatorView removeFromSuperview];
|
||||
[self.modeScrollView addSubview:self.indicatorView];
|
||||
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
||||
@ -585,18 +596,10 @@
|
||||
}];
|
||||
}
|
||||
else
|
||||
self.indicatorView.alpha = 0;
|
||||
self.indicatorView.hidden = YES;
|
||||
} );
|
||||
}];
|
||||
|
||||
// Site Counter
|
||||
if ([mainSite isKindOfClass:[MPGeneratedSiteEntity class]])
|
||||
self.counterLabel.text = strf( @"%lu", (unsigned long)((MPGeneratedSiteEntity *)mainSite).counter );
|
||||
|
||||
// Site Login Name
|
||||
self.loginNameField.enabled = self.passwordField.enabled = //
|
||||
[self.loginNameField isFirstResponder] || [self.passwordField isFirstResponder];
|
||||
|
||||
[self.contentView layoutIfNeeded];
|
||||
}];
|
||||
}
|
||||
@ -616,8 +619,9 @@
|
||||
range:NSMakeRange( s, [self.fuzzyGroups[f] length] )];
|
||||
}
|
||||
|
||||
[attributedSiteName appendAttributedString:stra(
|
||||
strf( @" - %@", self.transientSite? @"Tap to create": [site.algorithm shortNameOfType:site.type] ), @{} )];
|
||||
if (self.transientSite)
|
||||
[attributedSiteName appendAttributedString:stra( @" – Tap to create", @{} )];
|
||||
|
||||
self.siteNameLabel.attributedText = attributedSiteName;
|
||||
}
|
||||
|
||||
|
@ -89,11 +89,11 @@
|
||||
if ([selectedSite isKindOfClass:[MPGeneratedSiteEntity class]])
|
||||
counter = ((MPGeneratedSiteEntity *)selectedSite).counter;
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{
|
||||
PearlNotMainQueue( ^{
|
||||
NSString *typeContent = [MPAlgorithmDefault generatePasswordForSiteNamed:name ofType:cellType
|
||||
withCounter:counter usingKey:[MPiOSAppDelegate get].key];
|
||||
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
PearlMainQueue( ^{
|
||||
[(UITextField *)[[tableView cellForRowAtIndexPath:indexPath] viewWithTag:2] setText:typeContent];
|
||||
} );
|
||||
} );
|
||||
|
@ -163,26 +163,24 @@
|
||||
return NO;
|
||||
|
||||
// Arbitrary URL to mpsites data.
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
|
||||
NSError *error;
|
||||
NSURLResponse *response;
|
||||
NSData *importedSitesData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url]
|
||||
returningResponse:&response error:&error];
|
||||
if (error)
|
||||
err( @"While reading imported sites from %@: %@", url, [error fullDescription] );
|
||||
if (!importedSitesData) {
|
||||
[PearlAlert showError:strf( @"Master Password couldn't read the import sites.\n\n%@", [error localizedDescription]?: error )];
|
||||
return;
|
||||
}
|
||||
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:
|
||||
^(NSData *importedSitesData, NSURLResponse *response, NSError *error) {
|
||||
if (error)
|
||||
err( @"While reading imported sites from %@: %@", url, [error fullDescription] );
|
||||
if (!importedSitesData) {
|
||||
[PearlAlert showError:strf( @"Master Password couldn't read the import sites.\n\n%@",
|
||||
[error localizedDescription]?: error )];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *importedSitesString = [[NSString alloc] initWithData:importedSitesData encoding:NSUTF8StringEncoding];
|
||||
if (!importedSitesString) {
|
||||
[PearlAlert showError:@"Master Password couldn't understand the import file."];
|
||||
return;
|
||||
}
|
||||
NSString *importedSitesString = [[NSString alloc] initWithData:importedSitesData encoding:NSUTF8StringEncoding];
|
||||
if (!importedSitesString) {
|
||||
[PearlAlert showError:@"Master Password couldn't understand the import file."];
|
||||
return;
|
||||
}
|
||||
|
||||
[self importSites:importedSitesString];
|
||||
} );
|
||||
[self importSites:importedSitesString];
|
||||
}] resume];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user