Added option to display passwords as clear text in entry list view. Fixes #347

This commit is contained in:
Michael Starke 2021-11-10 20:38:03 +01:00
parent 5d4d0a626b
commit 95184ed2ec
4 changed files with 61 additions and 18 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19455" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19455"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -16,16 +16,16 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="336">
<rect key="frame" x="0.0" y="0.0" width="695" height="523"/>
<rect key="frame" x="0.0" y="0.0" width="691" height="331"/>
<subviews>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="54">
<rect key="frame" x="0.0" y="0.0" width="690" height="476"/>
<rect key="frame" x="0.0" y="0.0" width="691" height="332"/>
<clipView key="contentView" id="4tt-2K-SPF">
<rect key="frame" x="0.0" y="0.0" width="690" height="476"/>
<rect key="frame" x="0.0" y="0.0" width="691" height="332"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" rowSizeStyle="automatic" headerView="676" viewBased="YES" id="55" customClass="MPTableView">
<rect key="frame" x="0.0" y="0.0" width="690" height="453"/>
<rect key="frame" x="0.0" y="0.0" width="691" height="309"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -128,11 +128,11 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="PasswordCell" id="428">
<rect key="frame" x="271" y="1" width="119" height="17"/>
<rect key="frame" x="271" y="1" width="118" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="429" customClass="NSSecureTextField">
<rect key="frame" x="1" y="1" width="117" height="16"/>
<rect key="frame" x="1" y="1" width="116" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="430">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -199,14 +199,14 @@
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="616">
<tableCellView identifier="MonospacedStringCell" id="616">
<rect key="frame" x="509" y="1" width="169" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="617">
<rect key="frame" x="1" y="1" width="167" height="16"/>
<rect key="frame" x="1" y="2" width="167" height="14"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="618">
<font key="font" metaFont="system"/>
<font key="font" size="12" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -236,7 +236,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" wantsLayer="YES" id="676">
<rect key="frame" x="0.0" y="0.0" width="690" height="23"/>
<rect key="frame" x="0.0" y="0.0" width="691" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>

View File

@ -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;
}

View File

@ -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;

View File

@ -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";