Skip to content

Commit

Permalink
Merge branch 'feature/enhance-password-change-settings-ux'
Browse files Browse the repository at this point in the history
  • Loading branch information
mstarke committed Aug 31, 2023
2 parents 265de27 + 7263704 commit 904b4b9
Show file tree
Hide file tree
Showing 11 changed files with 982 additions and 343 deletions.
10 changes: 4 additions & 6 deletions MacPass.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2031,12 +2031,12 @@
4C77E35915B84A240093A587 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
CLASSPREFIX = MP;
LastUpgradeCheck = 1400;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "HicknHack Software GmbH";
TargetAttributes = {
4C77E36115B84A240093A587 = {
DevelopmentTeam = 55SM4L4Z97;
ProvisioningStyle = Automatic;
};
};
Expand Down Expand Up @@ -3256,7 +3256,7 @@
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = "${CURRENT_PROJECT_VERSION}";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 55SM4L4Z97;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -3278,7 +3278,6 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
STRIP_STYLE = debugging;
WRAPPER_EXTENSION = app;
};
name = Debug;
Expand All @@ -3295,7 +3294,7 @@
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = "${CURRENT_PROJECT_VERSION}";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 55SM4L4Z97;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -3318,7 +3317,6 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
STRIP_STYLE = debugging;
WRAPPER_EXTENSION = app;
};
name = Release;
Expand Down
2 changes: 1 addition & 1 deletion MacPass.xcodeproj/xcshareddata/xcschemes/MacPass.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
LastUpgradeVersion = "1430"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
604 changes: 317 additions & 287 deletions MacPass/Base.lproj/DatabaseSettingsWindow.xib

Large diffs are not rendered by default.

58 changes: 29 additions & 29 deletions MacPass/Base.lproj/GeneralPreferences.xib

Large diffs are not rendered by default.

172 changes: 172 additions & 0 deletions MacPass/MPAdvancedDatabaseSettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,45 @@
//

#import "MPAdvancedDatabaseSettingsViewController.h"
#import "MPDocument.h"
#import "MPDayCountFormatter.h"
#import "KPKNode+IconImage.h"

#import <KeePassKit/KeePassKit.h>
#import <HNHUi/HNHUi.h>

@interface MPAdvancedDatabaseSettingsViewController ()

@property (strong) IBOutlet NSButton *enableHistoryCheckButton;
@property (strong) IBOutlet NSTextField *historyMaximumItemsTextField;
@property (strong) IBOutlet NSStepper *historyMaximumItemsStepper;

@property (strong) IBOutlet NSTextField *historyMaximumSizeTextField;
@property (strong) IBOutlet NSStepper *historyMaximumSizeStepper;

@property (strong) IBOutlet NSButton *enableTrashCheckButton;
@property (strong) IBOutlet NSButton *emptyTrashOnQuitCheckButton;
@property (strong) IBOutlet NSPopUpButton *selectTrashGoupPopUpButton;
@property (strong) IBOutlet NSTextField *defaultUsernameTextField;
@property (strong) IBOutlet NSPopUpButton *templateGroupPopUpButton;

@property (strong) IBOutlet NSButton *recommendKeyChangeCheckButton;
@property (strong) IBOutlet NSButton *enforceKeyChangeCheckButton;
@property (strong) IBOutlet NSButton *enforceKeyChangeOnceCheckButton;
@property (strong) IBOutlet NSTextField *recommendKeyChangeIntervalTextField;
@property (strong) IBOutlet NSStepper *recommendKeyChangeIntervalStepper;
@property (strong) IBOutlet NSTextField *enforceKeyChangeIntervalTextField;
@property (strong) IBOutlet NSStepper *enforceKeyChangeIntervalStepper;

@property (assign) BOOL enableHistory;
@property (assign) NSInteger maxiumHistoryItems;
@property (assign) NSInteger maxiumHistorySize;

@property (assign) BOOL enforceKeyChange;
@property (assign) BOOL recommendKeyChange;
@property (assign) NSInteger enforceKeyChangeInterval;
@property (assign) NSInteger recommendKeyChangeInterval;

@end

@implementation MPAdvancedDatabaseSettingsViewController
Expand All @@ -19,4 +55,140 @@ - (void)viewDidLoad {
// Do view setup here.
}

- (void)_setupAdvancedTab {
/* history */
MPDocument *document = (MPDocument*)self.view.window.windowController.document;
KPKTree *tree = document.tree;

self.enableHistory = tree.metaData.isHistoryEnabled;
[self.enableHistoryCheckButton bind:NSValueBinding
toObject:self
withKeyPath:NSStringFromSelector(@selector(enableHistory))
options:nil];

/* history size */
self.maxiumHistorySize = tree.metaData.historyMaxSize;
self.historyMaximumSizeStepper.minValue = 0;
self.historyMaximumSizeStepper.maxValue = NSIntegerMax;
self.historyMaximumSizeStepper.increment = 1024*1024; // 1MB
[self.historyMaximumSizeStepper bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enableHistory)) options:nil];
[self.historyMaximumSizeStepper bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(maxiumHistorySize)) options:nil];
[self.historyMaximumSizeTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enableHistory)) options:nil];
[self.historyMaximumSizeTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(maxiumHistorySize)) options:nil];

/* history count */
self.maxiumHistoryItems = MAX(0,tree.metaData.historyMaxItems); // prevent -1 form showing up directly
self.historyMaximumItemsStepper.minValue = 0;
self.historyMaximumItemsStepper.maxValue = NSIntegerMax;
self.historyMaximumItemsStepper.increment = 1;
[self.historyMaximumItemsStepper bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enableHistory)) options:nil];
[self.historyMaximumItemsStepper bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(maxiumHistoryItems)) options:nil];
[self.historyMaximumItemsTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enableHistory)) options:nil];
[self.historyMaximumItemsTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(maxiumHistoryItems)) options:nil];

/* trash */
HNHUISetStateFromBool(self.enableTrashCheckButton, tree.metaData.useTrash);
self.selectTrashGoupPopUpButton.enabled = tree.metaData.useTrash;
[self.enableTrashCheckButton bind:NSValueBinding toObject:self.selectTrashGoupPopUpButton withKeyPath:NSEnabledBinding options:nil];
[self _updateTrashFolders:tree];

/* default username */
self.defaultUsernameTextField.stringValue = tree.metaData.defaultUserName;
self.defaultUsernameTextField.editable = YES;
[self _updateTemplateGroup:tree];

/* key changes */
self.enforceKeyChange = tree.metaData.enforceMasterKeyChange;
self.recommendKeyChange = tree.metaData.recommendMasterKeyChange;
HNHUISetStateFromBool(self.enforceKeyChangeOnceCheckButton, tree.metaData.enforceMasterKeyChangeOnce);

[self.enforceKeyChangeCheckButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enforceKeyChange)) options:nil];
[self.recommendKeyChangeCheckButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChange)) options:nil];

/* intervals use -1 to encode disabled, do not show this in text fields! */
self.enforceKeyChangeInterval = MAX(0,tree.metaData.masterKeyChangeEnforcementInterval);
self.enforceKeyChangeIntervalStepper.minValue = 0;
self.enforceKeyChangeIntervalStepper.maxValue = NSIntegerMax;
self.enforceKeyChangeIntervalStepper.increment = 1; // 1 day steps
[self.enforceKeyChangeIntervalStepper bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enforceKeyChange)) options:nil];
[self.enforceKeyChangeIntervalStepper bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enforceKeyChangeInterval)) options:nil];
[self.enforceKeyChangeIntervalTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enforceKeyChange)) options:nil];
[self.enforceKeyChangeIntervalTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enforceKeyChangeInterval)) options:nil];

NSString *valueFormat = NSLocalizedString(@"EVERY_%ld_DAYS", @"Recommend/Enforce key change intervall format");

((MPDayCountFormatter *)self.enforceKeyChangeIntervalTextField.formatter).valueFormat = valueFormat;

self.recommendKeyChangeInterval = MAX(0,tree.metaData.masterKeyChangeRecommendationInterval);
self.recommendKeyChangeIntervalStepper.minValue = 0;
self.recommendKeyChangeIntervalStepper.maxValue = NSIntegerMax;
self.recommendKeyChangeIntervalStepper.increment = 1; // 1 day steps
[self.recommendKeyChangeIntervalStepper bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChange)) options:nil];
[self.recommendKeyChangeIntervalStepper bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChangeInterval)) options:nil];
[self.recommendKeyChangeIntervalTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChange)) options:nil];
[self.recommendKeyChangeIntervalTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChangeInterval)) options:nil];
((MPDayCountFormatter *)self.recommendKeyChangeIntervalTextField.formatter).valueFormat = valueFormat;
}

- (void)_updateTrashFolders:(KPKTree *)tree {
NSMenu *menu = [self _buildTrashTreeMenu:tree];
self.selectTrashGoupPopUpButton.menu = menu;
}

- (void)_updateTemplateGroup:(KPKTree *)tree {
NSMenu *menu = [self _buildTemplateTreeMenu:tree];
self.templateGroupPopUpButton.menu = menu;
}

- (NSMenu *)_buildTrashTreeMenu:(KPKTree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.trashUuid];

NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"AUTOCREATE_TRASH_FOLDER", @"Menu item for automatic trash creation")
action:NULL
keyEquivalent:@""];
selectItem.enabled = YES;
[menu insertItem:selectItem atIndex:0];

return menu;
}

- (NSMenu *)_buildTemplateTreeMenu:(KPKTree *)tree {
NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.entryTemplatesGroupUuid];

NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"NO_TEMPLATE_GROUP", @"Menu item to reset the template groups")
action:NULL
keyEquivalent:@""];
selectItem.enabled = YES;
[menu insertItem:selectItem atIndex:0];

return menu;
}


- (NSMenu *)_buildTreeMenu:(KPKTree *)tree preselect:(NSUUID *)uuid {
NSMenu *menu = [[NSMenu alloc] init];
menu.autoenablesItems = NO;
for(KPKGroup *group in tree.root.groups) {
[self _insertMenuItemsForGroup:group atLevel:0 inMenu:menu preselect:uuid];
}
return menu;
}

- (void)_insertMenuItemsForGroup:(KPKGroup *)group atLevel:(NSUInteger)level inMenu:(NSMenu *)menu preselect:(NSUUID *)uuid{
NSMenuItem *groupItem = [[NSMenuItem alloc] init];
groupItem.image = group.iconImage;
groupItem.title = group.title;
groupItem.representedObject = group;
groupItem.enabled = YES;
if(uuid && [group.uuid isEqual:uuid]) {
groupItem.state = NSOnState;
}
groupItem.indentationLevel = level;
[menu addItem:groupItem];
for(KPKGroup *childGroup in group.groups) {
[self _insertMenuItemsForGroup:childGroup atLevel:level + 1 inMenu:menu preselect:uuid];
}
}


@end
6 changes: 3 additions & 3 deletions MacPass/MPAdvancedDatabaseSettingsViewController.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
Expand All @@ -16,7 +16,7 @@
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<point key="canvasLocation" x="-229" y="178"/>
<point key="canvasLocation" x="260" y="-61"/>
</customView>
</objects>
</document>
1 change: 1 addition & 0 deletions MacPass/MPDatabaseSettingsWindowController.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
@property (weak) IBOutlet NSStepper *recommendKeyChangeIntervalStepper;
@property (weak) IBOutlet NSTextField *enforceKeyChangeIntervalTextField;
@property (weak) IBOutlet NSStepper *enforceKeyChangeIntervalStepper;
@property (strong) IBOutlet NSTextField *lastKeyChangeTextField;

- (void)showSettingsTab:(MPDatabaseSettingsTab)tab;

Expand Down
14 changes: 14 additions & 0 deletions MacPass/MPDatabaseSettingsWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,20 @@ - (void)_setupAdvancedTab:(KPKTree *)tree {
[self.recommendKeyChangeIntervalTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChange)) options:nil];
[self.recommendKeyChangeIntervalTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(recommendKeyChangeInterval)) options:nil];
((MPDayCountFormatter *)self.recommendKeyChangeIntervalTextField.formatter).valueFormat = valueFormat;

if(nil != tree.metaData.masterKeyChanged) {
NSString *keyChangeTextFormat = NSLocalizedString(@"LAST_DATABASE_KEY_CHANGE_DATE_%@", "Information about last key change date");
NSDateFormatter *changeDateFormatter = [[NSDateFormatter alloc] init];
changeDateFormatter.timeStyle = NSDateFormatterNoStyle;
changeDateFormatter.dateStyle = NSDateFormatterLongStyle;

NSString *keyChangeDateString = [changeDateFormatter stringFromDate:tree.metaData.masterKeyChanged];

self.lastKeyChangeTextField.stringValue = [NSString stringWithFormat:keyChangeTextFormat, keyChangeDateString];
}
else {
self.lastKeyChangeTextField.stringValue = NSLocalizedString(@"DATABASE_KEY_NEVER_CHANGED", "Displayed when the databse key was never changed/is not set");
}
}

- (void)_updateFirstResponder {
Expand Down
Loading

0 comments on commit 904b4b9

Please sign in to comment.