4 Commits

Author SHA1 Message Date
michael starke
c1b47bdb77 Enhanced password input to check and verify
Added repeat password input in settings
New databases without password request on (it's not changed on file until the saved)
2013-07-19 01:39:52 +02:00
michael starke
0e102d3f0f Saving last state of Inspector (last document wins) 2013-07-18 21:23:32 +02:00
michael starke
d4c7d49d6f Fixed issue with window restoration 2013-07-18 21:16:56 +02:00
michael starke
0144e3c21f Bumped Build number 2013-07-18 04:36:45 +02:00
12 changed files with 765 additions and 310 deletions

2
HNHUi

Submodule HNHUi updated: 32be9c7cea...c32f87da30

View File

@@ -138,6 +138,8 @@
4C669B9F16760ED100DD0774 /* RandomStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7516760ED100DD0774 /* RandomStream.m */; };
4C669BA016760ED100DD0774 /* Salsa20RandomStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7716760ED100DD0774 /* Salsa20RandomStream.m */; };
4C669BA216760ED100DD0774 /* UUID.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C669B7B16760ED100DD0774 /* UUID.m */; };
4C67D33017981A2B00A7BDFC /* HNHTokenField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */; };
4C67D33317981ABA00A7BDFC /* HNHTokenFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */; };
4C69A73A16D589DF00EC1B1A /* HNHGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C69A73916D589DF00EC1B1A /* HNHGradientView.m */; };
4C6D1D25178579570014C5A5 /* 48_FolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */; };
4C6D1D27178586CA0014C5A5 /* 99_AddFolderTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C6D1D26178586CA0014C5A5 /* 99_AddFolderTemplate.pdf */; };
@@ -477,6 +479,10 @@
4C669B7716760ED100DD0774 /* Salsa20RandomStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Salsa20RandomStream.m; sourceTree = "<group>"; };
4C669B7A16760ED100DD0774 /* UUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UUID.h; sourceTree = "<group>"; };
4C669B7B16760ED100DD0774 /* UUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UUID.m; sourceTree = "<group>"; };
4C67D32E17981A2B00A7BDFC /* HNHTokenField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHTokenField.h; sourceTree = "<group>"; };
4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTokenField.m; sourceTree = "<group>"; };
4C67D33117981ABA00A7BDFC /* HNHTokenFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHTokenFieldCell.h; sourceTree = "<group>"; };
4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHTokenFieldCell.m; sourceTree = "<group>"; };
4C69A73816D589DF00EC1B1A /* HNHGradientView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHGradientView.h; sourceTree = "<group>"; };
4C69A73916D589DF00EC1B1A /* HNHGradientView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHGradientView.m; sourceTree = "<group>"; };
4C6D1D24178579570014C5A5 /* 48_FolderTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 48_FolderTemplate.pdf; sourceTree = "<group>"; };
@@ -1329,6 +1335,10 @@
4CC3AAB9175F4983003EF01B /* HNHRoundedTextFieldCell.m */,
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */,
4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */,
4C67D32E17981A2B00A7BDFC /* HNHTokenField.h */,
4C67D32F17981A2B00A7BDFC /* HNHTokenField.m */,
4C67D33117981ABA00A7BDFC /* HNHTokenFieldCell.h */,
4C67D33217981ABA00A7BDFC /* HNHTokenFieldCell.m */,
4C58BD4D176370B100B8178C /* HNHBadgedTextField.h */,
4C58BD4E176370B100B8178C /* HNHBadgedTextField.m */,
4CAF62FA1763604000CD7084 /* HNHBadgedTextFieldCell.h */,
@@ -1808,6 +1818,8 @@
4C055E74179620BF00BD2BAB /* NSString+CommandString.m in Sources */,
4CC0D2CE17974A47000B4BDA /* MPCustomFieldTableViewDelegate.m in Sources */,
4CC0D2D117974A5A000B4BDA /* MPAttachmentTableViewDelegate.m in Sources */,
4C67D33017981A2B00A7BDFC /* HNHTokenField.m in Sources */,
4C67D33317981ABA00A7BDFC /* HNHTokenFieldCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,7 @@
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string>
<string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<string key="NSFrameAutosaveName">DatabaseWindow</string>
<bool key="NSWindowIsRestorable">YES</bool>
@@ -65,6 +65,7 @@
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSIsVertical">YES</bool>
<int key="NSDividerStyle">2</int>
<string key="NSAutosaveName"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">

View File

@@ -18,9 +18,11 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) {
@class MPDocument;
@class HNHRoundedSecureTextField;
@interface MPDatabaseSettingsWindowController : NSWindowController
@interface MPDatabaseSettingsWindowController : NSWindowController <NSTextFieldDelegate>
@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;

View File

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

View File

@@ -17,6 +17,7 @@
#import "MPActionHelper.h"
#import "MPDatabaseSettingsWindowController.h"
#import "MPConstants.h"
#import "MPSettingsHelper.h"
NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCurrentItemChangedNotification";
@@ -62,9 +63,6 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark View Handling
@@ -94,6 +92,11 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+2 forSubviewAtIndex:0];
[_splitView setHoldingPriority:NSLayoutPriorityDefaultLow+1 forSubviewAtIndex:2];
BOOL showInspector = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyShowInspector];
if(!showInspector) {
[inspectorView removeFromSuperview];
}
[[self window] setDelegate:self];
MPDocument *document = [self document];
@@ -103,6 +106,8 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
else {
[self showEntries];
}
[_splitView setAutosaveName:@"SplitView"];
}
- (void)_setContentViewController:(MPViewController *)viewController {
@@ -252,18 +257,21 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
- (void)toggleInspector:(id)sender {
NSView *inspectorView = [_inspectorViewController view];
BOOL inspectorVisible = NO;
if([inspectorView superview]) {
//[inspectorView animator]
[inspectorView removeFromSuperview];
}
else {
// Remove contraint on view removal.
inspectorVisible = YES;
[_splitView addSubview:inspectorView];
[_splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[inspectorView(>=200)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(inspectorView)]];
}
[[NSUserDefaults standardUserDefaults] setBool:inspectorVisible forKey:kMPSettingsKeyShowInspector];
}
- (void)showEntries {
@@ -275,7 +283,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[[contentView subviews][0] removeFromSuperviewWithoutNeedingDisplay];
}
[contentView addSubview:_splitView];
[_splitView adjustSubviews];
//[_splitView adjustSubviews];
NSView *outlineView = [_outlineViewController view];
NSView *inspectorView = [_inspectorViewController view];
NSView *entryView = [_entryViewController view];
@@ -321,7 +329,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
if(removeInspector) {
[inspectorView removeFromSuperview];
}
[contentView layout];
[contentView layoutSubtreeIfNeeded];
MPDocument *document = [self document];
document.locked = NO;
@@ -332,6 +340,7 @@ NSString *const MPCurrentItemChangedNotification = @"com.hicknhack.macpass.MPCur
[_outlineViewController showOutline];
}
#pragma mark NSWindowDelegate
- (void)windowDidUpdate:(NSNotification *)notification {
id firstResonder = [[self window] firstResponder];
@@ -340,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

View File

@@ -27,6 +27,9 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyLockOnSleep;
APPKIT_EXTERN NSString *const kMPSettingsKeyIdleLockTimeOut;
/* Autosaving states */
APPKIT_EXTERN NSString *const kMPSettingsKeyShowInspector;
typedef NS_ENUM(NSUInteger, MPPasswordEncoding) {
MPPasswordEncodingUTF8,
MPPasswordEncodingASCII,

View File

@@ -17,6 +17,7 @@ NSString *const kMPSettingsKeyEnableHttpServer = @"EnableHttpServer";
NSString *const kMPSettingsKeyShowMenuItem = @"ShowMenuItem";
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
@implementation MPSettingsHelper
@@ -26,6 +27,7 @@ NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
+ (NSDictionary *)_standardDefaults {
return @{
kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default
kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds
kMPSettingsKeyClearPasteboardOnQuit: @YES,
kMPSettingsKeyOpenEmptyDatabaseOnLaunch: @NO,

View File

@@ -44,11 +44,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.3.3</string>
<string>0.3.4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2508</string>
<string>2514</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>

Binary file not shown.

Binary file not shown.