diff --git a/MacPass/EntryView.xib b/MacPass/EntryView.xib index a663584e..93081a00 100644 --- a/MacPass/EntryView.xib +++ b/MacPass/EntryView.xib @@ -1,8 +1,8 @@ - + - + @@ -16,16 +16,16 @@ - + - + - + - + @@ -128,11 +128,11 @@ - + - + @@ -199,14 +199,14 @@ - + - + - + @@ -236,7 +236,7 @@ - + diff --git a/MacPass/MPEntryViewController.m b/MacPass/MPEntryViewController.m index 0823f0a1..d42460d5 100644 --- a/MacPass/MPEntryViewController.m +++ b/MacPass/MPEntryViewController.m @@ -69,6 +69,7 @@ NSString *const MPEntryTableHistoryColumnIdentifier = @"MPEntryTableHistoryColum NSString *const _MPTableImageCellView = @"ImageCell"; NSString *const _MPTableStringCellView = @"StringCell"; NSString *const _MPTableSecurCellView = @"PasswordCell"; +NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell"; @interface MPEntryViewController () { BOOL _isDisplayingContextBar; @@ -86,6 +87,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; @property (strong) NSLayoutConstraint *contextBarTopConstraint; @property (nonatomic, strong) MPEntryTableDataSource *dataSource; +@property (nonatomic) BOOL displayClearTextPasswords; @end @@ -104,6 +106,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; _dataSource = [[MPEntryTableDataSource alloc] init]; _dataSource.viewController = self; _contextBarViewController = [[MPContextBarViewController alloc] init]; + _displayClearTextPasswords = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList]; + + [self bind:NSStringFromSelector(@selector(displayClearTextPasswords)) + toObject:NSUserDefaultsController.sharedUserDefaultsController + withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList] + options:nil]; + [self _setupEntryBindings]; } return self; @@ -206,7 +215,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; // bind NSArrayController sorting so that sort order gets auto-saved // see: http://simx.me/technonova/software_development/sort_descriptors_nstableview_bindings_a.html [self.entryArrayController bind:NSSortDescriptorsBinding - toObject:[NSUserDefaultsController sharedUserDefaultsController] + toObject:NSUserDefaultsController.sharedUserDefaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEntryTableSortDescriptors] options:@{ NSValueTransformerNameBindingOption: NSUnarchiveFromDataTransformerName }]; @@ -223,6 +232,17 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; } } +- (void)setDisplayClearTextPasswords:(BOOL)displayClearTextPasswords { + if(_displayClearTextPasswords == displayClearTextPasswords) { + return; + } + _displayClearTextPasswords = displayClearTextPasswords; + NSTableColumn *passwordColumn = [self.entryTable tableColumnWithIdentifier:MPEntryTablePasswordColumnIdentifier]; + if(!passwordColumn.isHidden) { + [self.entryTable reloadData]; + } +} + - (NSResponder *)reconmendedFirstResponder { return self.entryTable; } @@ -272,6 +292,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; BOOL isHistoryColumn = [tableColumn.identifier isEqualToString:MPEntryTableHistoryColumnIdentifier]; NSTableCellView *view = nil; + BOOL displayClearTextPasswords = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList]; if(isTitleColumn || isGroupColumn) { view = [tableView makeViewWithIdentifier:_MPTableImageCellView owner:self]; [view.textField unbind:NSValueBinding]; @@ -302,7 +323,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; [view.imageView bind:NSValueBinding toObject:view withKeyPath:parentIconImageKeyPath options:nil]; } } - else if(isPasswordColum) { + else if(isPasswordColum && !displayClearTextPasswords) { view = [tableView makeViewWithIdentifier:_MPTableSecurCellView owner:self]; NSString *passwordKeyPath = [NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(objectValue)), @@ -310,15 +331,19 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; NSDictionary *options = @{ NSValueTransformerBindingOption : [NSValueTransformer valueTransformerForName:MPStringLengthValueTransformerName] }; [view.textField bind:NSValueBinding toObject:view withKeyPath:passwordKeyPath options:options]; } - else { - view = [tableView makeViewWithIdentifier:_MPTableStringCellView owner:self]; + else { + if(isPasswordColum) { + view = [tableView makeViewWithIdentifier:_MPTableMonoSpacedStringCellView owner:self]; + } + else { + view = [tableView makeViewWithIdentifier:_MPTableStringCellView owner:self]; + } [view.textField unbind:NSValueBinding]; view.textField.stringValue = @""; if(!isModifedColumn && !isCreatedColumn) { /* clean up old formatter that might be left */ view.textField.formatter = nil; } - if(isModifedColumn || isCreatedColumn) { if(!view.textField.formatter) { /* Just use one formatter instance since it's expensive to create */ @@ -382,6 +407,12 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; NSStringFromSelector(@selector(history))]; [view.textField bind:NSValueBinding toObject:view withKeyPath:historyCountKeyPath options:nil]; } + else if(isPasswordColum) { + NSString *passwordKeyPath = [NSString stringWithFormat:@"%@.%@", + NSStringFromSelector(@selector(objectValue)), + NSStringFromSelector(@selector(password))]; + [view.textField bind:NSValueBinding toObject:view withKeyPath:passwordKeyPath options:nil]; + } } return view; } @@ -646,7 +677,6 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; [headerMenu addItemWithTitle:NSLocalizedString(@"CREATED", "Menu item to toggle display of created date column in entry table") action:NULL keyEquivalent:@""]; [headerMenu addItemWithTitle:NSLocalizedString(@"HISTORY", "Menu item to toggle display of history count column in entry table") action:NULL keyEquivalent:@""]; - NSArray *identifier = @[ MPEntryTableTitleColumnIdentifier, MPEntryTableUserNameColumnIdentifier, MPEntryTablePasswordColumnIdentifier, @@ -664,6 +694,14 @@ NSString *const _MPTableSecurCellView = @"PasswordCell"; [item bind:NSValueBinding toObject:column withKeyPath:NSHiddenBinding options:options]; } + + [headerMenu addItem:[NSMenuItem separatorItem]]; + NSMenuItem *showPasswordsItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SHOW_CLEAR_TEXT_PASSWORDS", "Menu item to toggle display type of passwords") action:NULL keyEquivalent:@""]; + [showPasswordsItem bind:NSValueBinding + toObject:NSUserDefaultsController.sharedUserDefaultsController + withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList] + options:nil]; + [headerMenu addItem:showPasswordsItem]; self.entryTable.headerView.menu = headerMenu; } diff --git a/MacPass/MPSettingsHelper.h b/MacPass/MPSettingsHelper.h index 36a7779a..f97aba44 100644 --- a/MacPass/MPSettingsHelper.h +++ b/MacPass/MPSettingsHelper.h @@ -36,6 +36,9 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyFileChangeStrategy; APPKIT_EXTERN NSString *const kMPSettingsKeyEnableAutosave; // if set to YES MacPass support Autosaving for documents APPKIT_EXTERN NSString *const kMPSettingsKeyFocusSearchAfterUnlock; // Enter search after unlocking the database +/* Entry Table Display */ +APPKIT_EXTERN NSString *const kMPSettingsKeyDisplayClearTextPasswordsInEntryList; + /* URL handling */ APPKIT_EXTERN NSString *const kMPSettingsKeyBrowserBundleId; APPKIT_EXTERN NSString *const kMPSettingsKeyUsePrivateBrowsingWhenOpeningURLs; diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index 072affa9..af0803d0 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -38,6 +38,8 @@ NSString *const kMPSettingsKeyFileChangeStrategy = @"Fi NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave"; NSString *const kMPSettingsKeyFocusSearchAfterUnlock = @"FocusSearchAfterUnlock"; +NSString *const kMPSettingsKeyDisplayClearTextPasswordsInEntryList = @"DisplayClearTextPasswordsInEntryList"; + NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep"; NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout"; NSString *const kMPSettingskeyLockOnScreenSleep = @"LockOnScreenSleep";