diff --git a/HNHUi b/HNHUi index f12405e3..c32f87da 160000 --- a/HNHUi +++ b/HNHUi @@ -1 +1 @@ -Subproject commit f12405e384eebdfb692e5750b4ff77b9be183bfb +Subproject commit c32f87da30386cb9b74c8a43cc173ad4584f329d diff --git a/MacPass/DatabaseSettingsWindow.xib b/MacPass/DatabaseSettingsWindow.xib index 44c7a059..fd571e73 100644 --- a/MacPass/DatabaseSettingsWindow.xib +++ b/MacPass/DatabaseSettingsWindow.xib @@ -68,7 +68,7 @@ 268 - {{463, 13}, {69, 32}} + {{473, 13}, {59, 32}} @@ -77,7 +77,7 @@ 67108864 134217728 - Save + OK LucidaGrande 13 @@ -100,7 +100,7 @@ {{13, 41}, {520, 246}} - + _NS:9 @@ -212,7 +212,7 @@ 2322 {278, 121} - + _NS:13 @@ -328,7 +328,7 @@ {{136, 17}, {280, 123}} - + _NS:9 133138 @@ -349,14 +349,15 @@ - + 256 268 - {{111, 125}, {68, 17}} + {{111, 140}, {68, 17}} + _NS:1535 YES @@ -379,8 +380,9 @@ Apple URL pasteboard type NSFilenamesPboardType - {{181, 91}, {170, 26}} + {{181, 74}, {170, 26}} + _NS:9 YES @@ -403,8 +405,9 @@ 268 - {{128, 95}, {51, 17}} + {{128, 78}, {51, 17}} + _NS:1535 YES @@ -423,9 +426,10 @@ 268 - {{184, 68}, {164, 19}} + {{184, 51}, {164, 19}} - + + _NS:9 YES @@ -451,9 +455,10 @@ 268 - {{356, 121}, {31, 25}} + {{356, 136}, {31, 25}} - + + _NS:22 YES @@ -479,8 +484,9 @@ 268 - {{356, 90}, {31, 25}} + {{356, 75}, {31, 25}} + _NS:22 YES @@ -507,8 +513,9 @@ 268 - {{184, 123}, {164, 22}} + {{184, 138}, {164, 22}} + _NS:9 YES @@ -528,9 +535,85 @@ NO + + + 268 + {{127, 108}, {52, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Repeat: + + _NS:1535 + + + + + NO + + + + 268 + {{184, 106}, {164, 22}} + + + + _NS:9 + YES + + 342884416 + 272630848 + + + _NS:9 + + YES + + + + NSAllRomanInputSourcesLocaleIdentifier + + + NO + + + + 268 + {{198, 168}, {137, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Missmatching Passwords + + LucidaGrande + 11 + 3100 + + _NS:1535 + + + + 1 + MSAwIDAAA + + + NO + {{10, 33}, {500, 200}} - + + + Password @@ -686,7 +769,7 @@ - + 256 @@ -694,7 +777,6 @@ 268 {{70, 159}, {307, 18}} - _NS:9 YES @@ -721,7 +803,6 @@ 268 {{70, 60}, {138, 18}} - _NS:9 YES @@ -748,7 +829,6 @@ 268 {{112, 37}, {187, 18}} - _NS:9 YES @@ -775,7 +855,6 @@ 268 {{111, 133}, {94, 17}} - _NS:1535 YES @@ -796,7 +875,6 @@ 268 {{111, 108}, {142, 17}} - _NS:1535 YES @@ -817,7 +895,6 @@ 268 {{256, 103}, {122, 26}} - _NS:9 YES @@ -893,7 +970,6 @@ 268 {{258, 131}, {96, 22}} - _NS:9 YES @@ -915,7 +991,6 @@ 268 {{359, 128}, {19, 27}} - _NS:1099 YES @@ -935,7 +1010,6 @@ 268 {{212, 56}, {220, 26}} - _NS:9 {750, 750} @@ -969,8 +1043,6 @@ {{10, 33}, {500, 200}} - - Advanced @@ -978,19 +1050,19 @@ - + 0 YES YES - + 268 - {{381, 13}, {82, 32}} + {{391, 13}, {82, 32}} @@ -1018,7 +1090,7 @@ - {{0, 0}, {2560, 1418}} + {{0, 0}, {1920, 1058}} {10000000000000, 10000000000000} YES @@ -1177,6 +1249,38 @@ 1050 + + + passwordRepeatTextField + + + + 1152 + + + + saveButton + + + + 1183 + + + + cancelButton + + + + 1201 + + + + errorTextField + + + + 1202 + @@ -2458,12 +2562,12 @@ 620 - + - 11 + 10 0 - - 11 + + 10 1 0.0 @@ -2474,12 +2578,12 @@ 24 2 - + - 5 + 6 0 - 5 + 6 1 0.0 @@ -2506,6 +2610,22 @@ 24 3 + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + 5 @@ -2522,38 +2642,6 @@ 24 3 - - - 6 - 0 - - 6 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 6 - 0 - - 6 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - 3 @@ -2570,6 +2658,22 @@ 24 3 + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + 5 @@ -2586,11 +2690,27 @@ 24 2 - + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + 3 0 - + 4 1 @@ -2618,15 +2738,31 @@ 24 3 - - + + + 9 + 0 + + 9 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + 3 0 3 1 - 55 + 15 1000 @@ -2634,6 +2770,86 @@ 9 3 + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 3 + 0 + + 4 + 1 + + 10 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + 5 @@ -2650,22 +2866,6 @@ 24 3 - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - 3 @@ -2714,6 +2914,22 @@ 24 2 + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + 5 @@ -2731,12 +2947,15 @@ 3 + + + + - - - + + @@ -2964,46 +3183,21 @@ - - 1016 - - - 1023 - - 1024 - - - - - 1026 - - - 1027 - - 1028 - - - 1029 - - 1031 - - - 1037 @@ -3043,16 +3237,6 @@ - - 1042 - - - - - 1043 - - - 1044 @@ -3098,11 +3282,6 @@ - - 1079 - - - 1080 @@ -3188,6 +3367,141 @@ + + 1120 + + + + + + + + 1121 + + + + + 1124 + + + + + + + + 1126 + + + + + 1128 + + + + + 1129 + + + + + 1130 + + + + + 1133 + + + + + 1134 + + + + + 1135 + + + + + 1146 + + + + + 1149 + + + + + 1150 + + + + + 1151 + + + + + 1177 + + + + + 1179 + + + + + 1187 + + + + + + 8 + 0 + + 0 + 1 + + 17 + + 1000 + + 3 + 9 + 1 + + + + + + 1188 + + + + + 1194 + + + + + 1195 + + + + + 1197 + + + + + 1199 + + + @@ -3201,14 +3515,9 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin HNHRoundedSecureTextField @@ -3218,8 +3527,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3235,7 +3542,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3243,6 +3549,35 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + HNHRoundedSecureTextField + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3400,22 +3735,29 @@ com.apple.InterfaceBuilder.CocoaPlugin + - - + + + + + + + - + + - - + - - + + + com.apple.InterfaceBuilder.CocoaPlugin @@ -3465,7 +3807,7 @@ - 1117 + 1202 @@ -3506,22 +3848,30 @@ + NSButton NSTextView NSTextField NSButton NSButton + NSTextField NSPathControl + HNHRoundedSecureTextField HNHRoundedSecureTextField NSButton NSButton NSButton NSButton NSButton + NSButton NSTabView NSPopUpButton NSButton + + cancelButton + NSButton + databaseDescriptionTextView NSTextView @@ -3538,10 +3888,18 @@ enableRecycleBinCheckButton NSButton + + errorTextField + NSTextField + keyfilePathControl NSPathControl + + passwordRepeatTextField + HNHRoundedSecureTextField + passwordTextField HNHRoundedSecureTextField @@ -3566,6 +3924,10 @@ protectUserNameCheckButton NSButton + + saveButton + NSButton + sectionTabView NSTabView diff --git a/MacPass/MPDatabaseSettingsWindowController.h b/MacPass/MPDatabaseSettingsWindowController.h index dc5593f8..72100b96 100644 --- a/MacPass/MPDatabaseSettingsWindowController.h +++ b/MacPass/MPDatabaseSettingsWindowController.h @@ -18,9 +18,11 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) { @class MPDocument; @class HNHRoundedSecureTextField; -@interface MPDatabaseSettingsWindowController : NSWindowController +@interface MPDatabaseSettingsWindowController : NSWindowController @property (weak) IBOutlet NSTabView *sectionTabView; +@property (weak) IBOutlet NSButton *saveButton; +@property (weak) IBOutlet NSButton *cancelButton; /* General Tab */ @property (weak) IBOutlet NSTextField *databaseNameTextField; @@ -28,8 +30,11 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) { /* Protection */ @property (weak) IBOutlet HNHRoundedSecureTextField *passwordTextField; +@property (weak) IBOutlet HNHRoundedSecureTextField *passwordRepeatTextField; @property (weak) IBOutlet NSPathControl *keyfilePathControl; @property (weak) IBOutlet NSButton *togglePasswordButton; +@property (weak) IBOutlet NSTextField *errorTextField; + - (IBAction)clearKey:(id)sender; - (IBAction)generateKey:(id)sender; diff --git a/MacPass/MPDatabaseSettingsWindowController.m b/MacPass/MPDatabaseSettingsWindowController.m index 917c912e..431154f3 100644 --- a/MacPass/MPDatabaseSettingsWindowController.m +++ b/MacPass/MPDatabaseSettingsWindowController.m @@ -14,6 +14,8 @@ #import "HNHRoundedSecureTextField.h" +#import "NSString+Empty.h" + #import "Kdb.h" #import "Kdb4Node.h" #import "KdbGroup+MPAdditions.h" @@ -24,6 +26,8 @@ @property (nonatomic,assign) BOOL trashEnabled; @property (nonatomic,assign) BOOL showPassword; +@property (nonatomic,assign) BOOL hasValidPasswordOrKey; +@property (nonatomic,weak) NSURL *keyURL; @end @@ -38,6 +42,7 @@ if(self) { _document = document; _showPassword = NO; + _hasValidPasswordOrKey = NO; } return self; } @@ -47,6 +52,9 @@ NSAssert(_document != nil, @"Document needs to be present"); + [self.saveButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil]; + [self.cancelButton bind:NSEnabledBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil]; + Kdb4Tree *tree = _document.treeV4; if( tree ) { [self _setupDatabase:tree]; @@ -64,7 +72,7 @@ /* Protection */ _document.password = [self.passwordTextField stringValue]; _document.key = [self.keyfilePathControl URL]; - + /* General */ _document.treeV4.databaseDescription = [self.databaseDescriptionTextView string]; _document.treeV4.databaseName = [self.databaseNameTextField stringValue]; @@ -72,7 +80,7 @@ /* Display */ /* Advanced */ - _document.treeV4.recycleBinEnabled = self.trashEnabled; + _document.treeV4.recycleBinEnabled = self.trashEnabled; NSMenuItem *menuItem = [self.selectRecycleBinGroupPopUpButton selectedItem]; KdbGroup *group = [menuItem representedObject]; [_document useGroupAsTrash:group]; @@ -109,15 +117,68 @@ [self.sectionTabView selectTabViewItemAtIndex:tab]; } +- (void)setShowPassword:(BOOL)showPassword { + if(_showPassword != showPassword) { + _showPassword = showPassword; + + [self.passwordRepeatTextField setStringValue:@""]; + [self _verifyPasswordAndKey]; + } +} + +- (void)setKeyURL:(NSURL *)keyURL { + _keyURL = keyURL; + [self _verifyPasswordAndKey]; +} + #pragma mark Actions - (IBAction)clearKey:(id)sender { - [self.keyfilePathControl setURL:nil]; + self.keyURL = nil; } - (IBAction)generateKey:(id)sender { } +#pragma makr NSTextFieldDelegate +- (void)controlTextDidChange:(NSNotification *)obj { + [self _verifyPasswordAndKey]; +} + #pragma mark Private Helper +- (void)_verifyPasswordAndKey { + NSString *password = [self.passwordTextField stringValue]; + NSString *repeat = [self.passwordRepeatTextField stringValue]; + BOOL hasKey = (self.keyURL != nil); + BOOL keyOk = YES; + if(hasKey) { + keyOk = [self.keyURL checkResourceIsReachableAndReturnError:nil]; + } + BOOL hasPassword = ![password isEmpty]; + BOOL passwordOk = YES; + if(hasPassword ) { + passwordOk = [password isEqualToString:repeat] || self.showPassword; + } + BOOL hasPasswordOrKey = (hasKey || hasPassword); + keyOk = hasKey ? keyOk : YES; + passwordOk = hasPassword ? passwordOk : YES; + self.hasValidPasswordOrKey = hasPasswordOrKey && passwordOk && keyOk; + + if(!hasPasswordOrKey) { + [self.errorTextField setStringValue:NSLocalizedString(@"ERROR_NO_PASSWORD_OR_KEYFILE", "Missing Key or Password")]; + return; // alldone + } + if(!passwordOk && !keyOk ) { + [self.errorTextField setStringValue:NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH_INVALID_KEYFILE", "Passwords do not match, keyfile is invalid")]; + } + else if(!passwordOk) { + [self.errorTextField setStringValue:NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH", "Passwords do not match")]; + } + else { + [self.errorTextField setStringValue:NSLocalizedString(@"ERROR_INVALID_KEYFILE", "Keyfile not valid")]; + } + +} + - (void)_setupDatabase:(Kdb4Tree *)tree { [self.databaseNameTextField setStringValue:tree.databaseName]; [self.databaseDescriptionTextView setString:tree.databaseDescription]; @@ -140,10 +201,21 @@ - (void)_setupPasswordTab:(Kdb4Tree *)tree { [self.passwordTextField setStringValue:_document.password ? _document.password : @""]; - [self.keyfilePathControl setURL:_document.key]; + [self.passwordRepeatTextField setStringValue:[self.passwordRepeatTextField stringValue]]; + self.keyURL = _document.key; + NSDictionary *negateOption = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }; [self.passwordTextField bind:@"showPassword" toObject:self withKeyPath:@"showPassword" options:nil]; [self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:@"showPassword" options:nil]; + [self.passwordRepeatTextField bind:NSEnabledBinding toObject:self withKeyPath:@"showPassword" options:negateOption]; + [self.errorTextField bind:NSHiddenBinding toObject:self withKeyPath:@"hasValidPasswordOrKey" options:nil]; + [self.keyfilePathControl bind:NSValueBinding toObject:self withKeyPath:@"keyURL" options:nil]; + + [self.passwordRepeatTextField setDelegate:self]; + [self.passwordTextField setDelegate:self]; + + /* Manually initate the first check */ + [self _verifyPasswordAndKey]; } - (void)_updateTrashFolders:(Kdb4Tree *)tree { @@ -154,7 +226,7 @@ - (NSMenu *)_buildTreeMenu:(Kdb4Tree *)tree { NSMenu *menu = [[NSMenu alloc] init]; [menu setAutoenablesItems:NO]; - + for(Kdb4Group *group in tree.root.groups) { NSMenuItem *groupItem = [[NSMenuItem alloc] init]; [groupItem setImage:group.icon]; diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index df213f3d..6c8b34a6 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -63,9 +63,6 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - - - } #pragma mark View Handling @@ -343,6 +340,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur [_outlineViewController showOutline]; } + #pragma mark NSWindowDelegate - (void)windowDidUpdate:(NSNotification *)notification { id firstResonder = [[self window] firstResponder]; @@ -351,10 +349,16 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur } _firstResponder = firstResonder; if([_firstResponder isKindOfClass:[NSView class]]) { - [self _updateCurrentItem:[NSNotification notificationWithName:@"dummy" object:_firstResponder ]]; + //self _updateCurrentItem:[NSNotification notificationWithName:@"dummy" object:_firstResponder ]]; } } +- (void)windowDidBecomeKey:(NSNotification *)notification { + MPDocument *document = [self document]; + if(!document.hasPasswordOrKey && document.decrypted) { + [self performSelector:@selector(editPassword:) withObject:nil afterDelay:0.5]; + } +} #pragma mark Helper diff --git a/MacPass/MacPass-Info.plist b/MacPass/MacPass-Info.plist index 8de34d18..dfb4ab2b 100644 --- a/MacPass/MacPass-Info.plist +++ b/MacPass/MacPass-Info.plist @@ -44,11 +44,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.3.3 + 0.3.4 CFBundleSignature ???? CFBundleVersion - 2511 + 2514 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index 9f0c6e57..7b575736 100644 Binary files a/MacPass/de.lproj/Localizable.strings and b/MacPass/de.lproj/Localizable.strings differ diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index e1987841..6b350ee4 100644 Binary files a/MacPass/en.lproj/Localizable.strings and b/MacPass/en.lproj/Localizable.strings differ