diff --git a/MacPass/Base.lproj/PasswordCreatorView.xib b/MacPass/Base.lproj/PasswordCreatorView.xib index 26324b93..3c5a0fac 100644 --- a/MacPass/Base.lproj/PasswordCreatorView.xib +++ b/MacPass/Base.lproj/PasswordCreatorView.xib @@ -23,17 +23,18 @@ + - + - + @@ -41,7 +42,7 @@ - + @@ -52,11 +53,11 @@ - + - + @@ -64,7 +65,7 @@ - + @@ -75,7 +76,7 @@ - + @@ -168,14 +169,14 @@ - + - + @@ -207,7 +208,7 @@ - + @@ -225,6 +226,13 @@ + @@ -258,16 +266,19 @@ - + + + + diff --git a/MacPass/MPPasswordCreatorViewController.h b/MacPass/MPPasswordCreatorViewController.h index afc20471..b444c87f 100644 --- a/MacPass/MPPasswordCreatorViewController.h +++ b/MacPass/MPPasswordCreatorViewController.h @@ -7,11 +7,13 @@ // #import "MPViewController.h" +@class KPKEntry; @interface MPPasswordCreatorViewController : MPViewController @property (copy, readonly) NSString *generatedPassword; @property (weak) id closeTarget; +@property (nonatomic, weak) KPKEntry *entry; @property (assign) BOOL allowsEntryDefaults; /** diff --git a/MacPass/MPPasswordCreatorViewController.m b/MacPass/MPPasswordCreatorViewController.m index 8a8dc0e0..d13b71bf 100644 --- a/MacPass/MPPasswordCreatorViewController.m +++ b/MacPass/MPPasswordCreatorViewController.m @@ -12,6 +12,8 @@ #import "MPUniqueCharactersFormatter.h" #import "MPSettingsHelper.h" +#import "KPKEntry.h" + /* 0 - 20 Terrible @@ -30,18 +32,11 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { MPPasswordStrong = 60 }; -typedef NS_ENUM(NSUInteger, MPDefaultDomain) { - MPEntryDomain, - MPGlobalDomain, -}; - #define MIN_PASSWORD_LENGTH 1 #define MAX_PASSWORD_LENGTH 256 -@interface MPPasswordCreatorViewController () { - MPPasswordCharacterFlags _characterFlags; - MPDefaultDomain _defaultDomain; -} +@interface MPPasswordCreatorViewController () + @property (nonatomic, copy) NSString *password; @property (copy) NSString *generatedPassword; @@ -58,12 +53,16 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { @property (weak) IBOutlet NSButton *setDefaultButton; @property (weak) IBOutlet NSTextField *entropyTextField; @property (weak) IBOutlet NSLevelIndicator *entropyIndicator; +@property (weak) IBOutlet NSButton *useEntryDefaultsButton; @property (nonatomic, copy) NSString *customString; @property (nonatomic, assign) BOOL useCustomString; @property (nonatomic, assign) NSUInteger passwordLength; @property (nonatomic, assign) CGFloat entropy; +@property (nonatomic, assign) BOOL useEntryDefaults; +@property (nonatomic, assign) MPPasswordCharacterFlags characterFlags; + @end @implementation MPPasswordCreatorViewController @@ -76,13 +75,10 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { _password = @""; - _passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength]; - _characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags]; - _useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString]; - _customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString]; _entropy = 0.0; - _defaultDomain = MPGlobalDomain; + _useEntryDefaults = NO; _allowsEntryDefaults = NO; + [self _setupDefaults]; } return self; } @@ -115,13 +111,19 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController]; [self.shouldCopyPasswordToPasteboardButton bind:NSValueBinding toObject:defaultsController withKeyPath:copyToPasteBoardKeyPath options:nil]; + if(self.allowsEntryDefaults) { + [self.useEntryDefaultsButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(useEntryDefaults)) options:nil]; + } + else { + [self.useEntryDefaultsButton setEnabled:self.allowsEntryDefaults]; + } + [self.numbersButton setTag:MPPasswordCharactersNumbers]; [self.upperCaseButton setTag:MPPasswordCharactersUpperCase]; [self.lowerCaseButton setTag:MPPasswordCharactersLowerCase]; [self.symbolsButton setTag:MPPasswordCharactersSymbols]; [self updateResponderChain]; - [self _updateSetDefaultButton]; [self reset]; } @@ -130,43 +132,31 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { [self _generatePassword:self]; } -#pragma mark - -#pragma mark Events - -- (void)flagsChanged:(NSEvent *)theEvent { - if(!self.allowsEntryDefaults) { - return; - } - BOOL altIsDown = (0 != ([NSEvent modifierFlags] & NSAlternateKeyMask)); - _defaultDomain = altIsDown ? MPEntryDomain : MPGlobalDomain; - [self _updateSetDefaultButton]; -} - #pragma mark - #pragma mark Actions - (IBAction)_generatePassword:(id)sender { - if(_useCustomString) { - if([[_customCharactersTextField stringValue] length] > 0) { - self.password = [[_customCharactersTextField stringValue] passwordWithLength:_passwordLength]; + if(self.useCustomString) { + if([[self.customCharactersTextField stringValue] length] > 0) { + self.password = [[self.customCharactersTextField stringValue] passwordWithLength:self.passwordLength]; } } else { - self.password = [NSString passwordWithCharactersets:_characterFlags length:_passwordLength]; + self.password = [NSString passwordWithCharactersets:self.characterFlags length:self.passwordLength]; } } - (IBAction)_toggleCharacters:(id)sender { - [_setDefaultButton setEnabled:YES]; - _characterFlags ^= [sender tag]; + [self.setDefaultButton setEnabled:YES]; + self.characterFlags ^= [sender tag]; self.useCustomString = NO; [self reset]; } - (IBAction)_usePassword:(id)sender { - self.generatedPassword = _password; + self.generatedPassword = self.password; if([self.shouldCopyPasswordToPasteboardButton state] == NSOnState) { - [[MPPasteBoardController defaultController] copyObjects:@[_password]]; + [[MPPasteBoardController defaultController] copyObjects:@[self.password]]; } [[self _findCloseTarget] performClose:nil]; } @@ -176,36 +166,67 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { } - (IBAction)_setDefault:(id)sender { - [[NSUserDefaults standardUserDefaults] setInteger:_passwordLength forKey:kMPSettingsKeyDefaultPasswordLength]; - [[NSUserDefaults standardUserDefaults] setInteger:_characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags]; - [[NSUserDefaults standardUserDefaults] setBool:_useCustomString forKey:kMPSettingsKeyPasswordUseCustomString]; - [[NSUserDefaults standardUserDefaults] setObject:[_customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString]; - - [_setDefaultButton setEnabled:NO]; + if(self.useEntryDefaults) { + NSMutableDictionary *entryDefaults = [[self _currentEntryDefaults] mutableCopy]; + if(!entryDefaults) { + entryDefaults = [[NSMutableDictionary alloc] initWithCapacity:4]; // we will only add one enty to new settings + } + entryDefaults[kMPSettingsKeyDefaultPasswordLength] = @(self.passwordLength); + entryDefaults[kMPSettingsKeyPasswordCharacterFlags] = @(self.characterFlags); + entryDefaults[kMPSettingsKeyPasswordUseCustomString] = @(self.useCustomString); + entryDefaults[kMPSettingsKeyPasswordCustomString] = [self.customCharactersTextField stringValue]; + NSMutableDictionary *availableDefaults = [[self _availableEntryDefaults] mutableCopy]; + if(!availableDefaults) { + availableDefaults = [[NSMutableDictionary alloc] initWithCapacity:1]; + } + availableDefaults[self.entry.uuid] = entryDefaults; + } + else { + [[NSUserDefaults standardUserDefaults] setInteger:self.passwordLength forKey:kMPSettingsKeyDefaultPasswordLength]; + [[NSUserDefaults standardUserDefaults] setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags]; + [[NSUserDefaults standardUserDefaults] setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString]; + [[NSUserDefaults standardUserDefaults] setObject:[self.customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString]; + } + [self.setDefaultButton setEnabled:NO]; } #pragma mark - #pragma mark Custom Setter +- (void)setUseEntryDefaults:(BOOL)useEntryDefaults { + if(self.useEntryDefaults != useEntryDefaults) { + _useEntryDefaults = useEntryDefaults; + [self _setupDefaults]; + [self reset]; + } +} + +- (void)setEntry:(KPKEntry *)entry { + if(_entry != entry) { + _entry = entry; + [self _setupDefaults]; + [self reset]; + } +} - (void)setPassword:(NSString *)password { if(![_password isEqualToString:password]) { _password = [password copy]; - NSString *customString = _useCustomString ? [_customCharactersTextField stringValue] : nil; - self.entropy = [password entropyWhithPossibleCharacterSet:_characterFlags orCustomCharacters:customString]; + NSString *customString = self.useCustomString ? [self.customCharactersTextField stringValue] : nil; + self.entropy = [password entropyWhithPossibleCharacterSet:self.characterFlags orCustomCharacters:customString]; } } - (void)setUseCustomString:(BOOL)useCustomString { - if(_useCustomString != useCustomString) { - [_setDefaultButton setEnabled:YES]; + if(self.useCustomString != useCustomString) { + [self.setDefaultButton setEnabled:YES]; _useCustomString = useCustomString; [self _resetCharacters]; } } - (void)setPasswordLength:(NSUInteger)passwordLength { - if(_passwordLength != passwordLength) { - [_setDefaultButton setEnabled:YES]; + if(self.passwordLength != passwordLength) { + [self.setDefaultButton setEnabled:YES]; _passwordLength = passwordLength; [self _generatePassword:nil]; } @@ -216,52 +237,64 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) { - (void)controlTextDidChange:(NSNotification *)obj { if([obj object] == self.customCharactersTextField) { - [_setDefaultButton setEnabled:YES]; + [self.setDefaultButton setEnabled:YES]; [self _generatePassword:nil]; } } #pragma mark - #pragma mark Helper +- (NSDictionary *)_availableEntryDefaults { + return [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyPasswordDefaultsForEntry]; +} -- (void)_updateSetDefaultButton { - - switch (_defaultDomain) { - case MPEntryDomain: - [self.setDefaultButton setTitle:NSLocalizedString(@"SET_DEFAULT_ENTRY_PASSWORD_RULE", "")]; - break; - - case MPGlobalDomain: - default: - [self.setDefaultButton setTitle:NSLocalizedString(@"SET_DEFAULT_GENERAL_PASSWORD_RULE", "")]; - break; +- (NSDictionary *)_currentEntryDefaults { + if(self.entry) { + return [self _availableEntryDefaults][self.entry.uuid]; + } + return nil; +} + +- (void)_setupDefaults { + NSDictionary *entryDefaults = [self _currentEntryDefaults]; + if(entryDefaults) { + self.passwordLength = [entryDefaults[kMPSettingsKeyDefaultPasswordLength] integerValue]; + self.characterFlags = [entryDefaults[kMPSettingsKeyPasswordCharacterFlags] integerValue]; + self.useCustomString = [entryDefaults[kMPSettingsKeyPasswordUseCustomString] boolValue]; + self.customString = [entryDefaults[kMPSettingsKeyPasswordCustomString] stringValue]; + } + else { + self.passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength]; + self.characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags]; + self.useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString]; + self.customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString]; } } - (void)_resetCharacters { - if(_useCustomString) { - [_customButton setState:NSOnState]; + if(self.useCustomString) { + [self.customButton setState:NSOnState]; } - [_customCharactersTextField setEnabled:_useCustomString]; - [_upperCaseButton setEnabled:!_useCustomString]; - [_lowerCaseButton setEnabled:!_useCustomString]; - [_numbersButton setEnabled:!_useCustomString]; - [_symbolsButton setEnabled:!_useCustomString]; + [self.customCharactersTextField setEnabled:_useCustomString]; + [self.upperCaseButton setEnabled:!_useCustomString]; + [self.lowerCaseButton setEnabled:!_useCustomString]; + [self.numbersButton setEnabled:!_useCustomString]; + [self.symbolsButton setEnabled:!_useCustomString]; - /* Set to defualts, if we got nothing */ - if(_characterFlags == 0) { - _characterFlags = MPPasswordCharactersAll; + /* Set to defaults, if we got nothing */ + if(self.characterFlags == 0) { + self.characterFlags = MPPasswordCharactersAll; } - const BOOL userLowercase = ( 0 != (MPPasswordCharactersLowerCase & _characterFlags)); - const BOOL useUppercase = ( 0 != (MPPasswordCharactersUpperCase & _characterFlags) ); - const BOOL useNumbers = ( 0 != (MPPasswordCharactersNumbers & _characterFlags) ); - const BOOL useSymbols = ( 0 != (MPPasswordCharactersSymbols & _characterFlags) ); + const BOOL userLowercase = ( 0 != (MPPasswordCharactersLowerCase & self.characterFlags)); + const BOOL useUppercase = ( 0 != (MPPasswordCharactersUpperCase & self.characterFlags) ); + const BOOL useNumbers = ( 0 != (MPPasswordCharactersNumbers & self.characterFlags) ); + const BOOL useSymbols = ( 0 != (MPPasswordCharactersSymbols & self.characterFlags) ); - [_upperCaseButton setState:useUppercase ? NSOnState : NSOffState]; - [_lowerCaseButton setState:userLowercase ? NSOnState : NSOffState]; - [_numbersButton setState:useNumbers ? NSOnState : NSOffState]; - [_symbolsButton setState:useSymbols ? NSOnState : NSOffState]; + [self.upperCaseButton setState:useUppercase ? NSOnState : NSOffState]; + [self.lowerCaseButton setState:userLowercase ? NSOnState : NSOffState]; + [self.numbersButton setState:useNumbers ? NSOnState : NSOffState]; + [self.symbolsButton setState:useSymbols ? NSOnState : NSOffState]; } - (id)_findCloseTarget { diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 64e4106f..6d7f7e5d 100644 Binary files a/MacPass/en.lproj/Localizable.strings and b/MacPass/en.lproj/Localizable.strings differ