Moved defaults cleanup for key file from document to app delegate.

Added clear button to settings to remove any keys stored
This commit is contained in:
michael starke
2014-02-12 20:51:36 +01:00
parent b82bc8c9e9
commit 422d74ee5c
6 changed files with 115 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment defaultVersion="1080" identifier="macosx"/> <deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
@@ -22,11 +22,11 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/> <customObject id="-3" userLabel="Application"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1"> <customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="400" height="401"/> <rect key="frame" x="0.0" y="0.0" width="400" height="418"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<box autoresizesSubviews="NO" title="General" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="928"> <box autoresizesSubviews="NO" title="General" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="928">
<rect key="frame" x="17" y="249" width="366" height="54"/> <rect key="frame" x="17" y="266" width="366" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView"> <view key="contentView">
<rect key="frame" x="1" y="1" width="364" height="38"/> <rect key="frame" x="1" y="1" width="364" height="38"/>
@@ -50,14 +50,14 @@
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box> </box>
<box autoresizesSubviews="NO" verticalHuggingPriority="251" title="Security" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="465"> <box autoresizesSubviews="NO" verticalHuggingPriority="251" title="Security" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="465">
<rect key="frame" x="17" y="16" width="366" height="229"/> <rect key="frame" x="17" y="16" width="366" height="246"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView"> <view key="contentView">
<rect key="frame" x="1" y="1" width="364" height="213"/> <rect key="frame" x="1" y="1" width="364" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="431"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="431">
<rect key="frame" x="16" y="185" width="124" height="17"/> <rect key="frame" x="16" y="202" width="124" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="17" id="803"/> <constraint firstAttribute="height" constant="17" id="803"/>
@@ -69,7 +69,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="419"> <popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="419">
<rect key="frame" x="179" y="182" width="170" height="22"/> <rect key="frame" x="179" y="199" width="170" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="165" id="877"/> <constraint firstAttribute="width" constant="165" id="877"/>
@@ -90,7 +90,7 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="447"> <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="447">
<rect key="frame" x="31" y="161" width="172" height="18"/> <rect key="frame" x="31" y="178" width="172" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="14" id="773"/> <constraint firstAttribute="height" constant="14" id="773"/>
@@ -101,7 +101,7 @@
</buttonCell> </buttonCell>
</button> </button>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="584"> <popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="584">
<rect key="frame" x="179" y="133" width="170" height="26"/> <rect key="frame" x="179" y="150" width="170" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="585"> <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="585">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@@ -119,7 +119,7 @@
</popUpButtonCell> </popUpButtonCell>
</popUpButton> </popUpButton>
<button translatesAutoresizingMaskIntoConstraints="NO" id="630"> <button translatesAutoresizingMaskIntoConstraints="NO" id="630">
<rect key="frame" x="31" y="114" width="121" height="18"/> <rect key="frame" x="31" y="131" width="121" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Lock after sleep" bezelStyle="regularSquare" imagePosition="left" enabled="NO" state="on" inset="2" id="631"> <buttonCell key="cell" type="check" title="Lock after sleep" bezelStyle="regularSquare" imagePosition="left" enabled="NO" state="on" inset="2" id="631">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@@ -127,7 +127,7 @@
</buttonCell> </buttonCell>
</button> </button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="805"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="805">
<rect key="frame" x="16" y="138" width="97" height="17"/> <rect key="frame" x="16" y="155" width="97" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Lock while idle" id="806"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Lock while idle" id="806">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -136,7 +136,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="bSt-Wf-FNZ"> <button verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="bSt-Wf-FNZ">
<rect key="frame" x="16" y="89" width="226" height="18"/> <rect key="frame" x="16" y="106" width="226" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Remember Keyfile for Databases" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="r6q-He-nYU"> <buttonCell key="cell" type="check" title="Remember Keyfile for Databases" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="r6q-He-nYU">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@@ -144,15 +144,26 @@
</buttonCell> </buttonCell>
</button> </button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU">
<rect key="frame" x="16" y="12" width="332" height="70"/> <rect key="frame" x="16" y="43" width="332" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="ACh-7H-42N"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" id="ACh-7H-42N">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<string key="title">Enabling this compromises security. If enabled, your preferences will contain mappings from database to keyfile. Once disabled, all values will be removed from the preferences. Key locations for databases without a password will not be saved.</string> <string key="title">Enabling this compromises security. If enabled, your preferences will contain mappings from database to keyfile. Key locations for databases without a password will not be saved.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oQr-FC-HkN">
<rect key="frame" x="156" y="7" width="196" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Clear all stored locations" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8Ri-2s-c39">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clearRememberdKeyFiles:" target="-1" id="Vlr-aK-ikW"/>
</connections>
</button>
</subviews> </subviews>
</view> </view>
<constraints> <constraints>
@@ -169,16 +180,19 @@
<constraint firstItem="419" firstAttribute="leading" secondItem="584" secondAttribute="leading" id="876"/> <constraint firstItem="419" firstAttribute="leading" secondItem="584" secondAttribute="leading" id="876"/>
<constraint firstItem="419" firstAttribute="bottom" secondItem="431" secondAttribute="bottom" id="916"/> <constraint firstItem="419" firstAttribute="bottom" secondItem="431" secondAttribute="bottom" id="916"/>
<constraint firstItem="630" firstAttribute="top" secondItem="805" secondAttribute="bottom" constant="8" id="952"/> <constraint firstItem="630" firstAttribute="top" secondItem="805" secondAttribute="bottom" constant="8" id="952"/>
<constraint firstItem="oQr-FC-HkN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="465" secondAttribute="leading" constant="16" id="XAl-D7-I6k"/>
<constraint firstItem="bSt-Wf-FNZ" firstAttribute="top" secondItem="630" secondAttribute="bottom" constant="11" id="XUI-7v-CA4"/> <constraint firstItem="bSt-Wf-FNZ" firstAttribute="top" secondItem="630" secondAttribute="bottom" constant="11" id="XUI-7v-CA4"/>
<constraint firstItem="805" firstAttribute="top" secondItem="447" secondAttribute="bottom" constant="8" symbolic="YES" id="XhN-Ce-ut7"/> <constraint firstItem="805" firstAttribute="top" secondItem="447" secondAttribute="bottom" constant="8" symbolic="YES" id="XhN-Ce-ut7"/>
<constraint firstItem="bSt-Wf-FNZ" firstAttribute="leading" secondItem="805" secondAttribute="leading" id="hcg-pe-Vtb"/> <constraint firstItem="bSt-Wf-FNZ" firstAttribute="leading" secondItem="805" secondAttribute="leading" id="hcg-pe-Vtb"/>
<constraint firstAttribute="bottom" secondItem="oQr-FC-HkN" secondAttribute="bottom" constant="11" id="tDO-89-9Iu"/>
<constraint firstItem="447" firstAttribute="top" secondItem="419" secondAttribute="bottom" constant="8" symbolic="YES" id="xZh-T3-USE"/> <constraint firstItem="447" firstAttribute="top" secondItem="419" secondAttribute="bottom" constant="8" symbolic="YES" id="xZh-T3-USE"/>
<constraint firstAttribute="trailing" secondItem="oQr-FC-HkN" secondAttribute="trailing" constant="16" id="xjj-cL-rTz"/>
</constraints> </constraints>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</box> </box>
<box autoresizesSubviews="NO" title="Startup" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="888"> <box autoresizesSubviews="NO" title="Startup" borderType="line" translatesAutoresizingMaskIntoConstraints="NO" id="888">
<rect key="frame" x="17" y="307" width="366" height="74"/> <rect key="frame" x="17" y="324" width="366" height="74"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView"> <view key="contentView">
<rect key="frame" x="1" y="1" width="364" height="58"/> <rect key="frame" x="1" y="1" width="364" height="58"/>
@@ -225,7 +239,7 @@
<constraint firstAttribute="trailing" secondItem="928" secondAttribute="trailing" constant="20" symbolic="YES" id="947"/> <constraint firstAttribute="trailing" secondItem="928" secondAttribute="trailing" constant="20" symbolic="YES" id="947"/>
<constraint firstItem="465" firstAttribute="top" secondItem="928" secondAttribute="bottom" constant="8" symbolic="YES" id="949"/> <constraint firstItem="465" firstAttribute="top" secondItem="928" secondAttribute="bottom" constant="8" symbolic="YES" id="949"/>
<constraint firstItem="465" firstAttribute="top" secondItem="1" secondAttribute="top" constant="156" id="950"/> <constraint firstItem="465" firstAttribute="top" secondItem="1" secondAttribute="top" constant="156" id="950"/>
<constraint firstAttribute="height" constant="401" id="Prx-WU-fwu"/> <constraint firstAttribute="height" constant="418" id="otH-bj-MWy"/>
<constraint firstAttribute="bottom" secondItem="465" secondAttribute="bottom" constant="20" symbolic="YES" id="uwq-az-XwJ"/> <constraint firstAttribute="bottom" secondItem="465" secondAttribute="bottom" constant="20" symbolic="YES" id="uwq-az-XwJ"/>
</constraints> </constraints>
</customView> </customView>

View File

@@ -22,16 +22,25 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
extern NSString *const MPDidChangeStoredKeyFilesSettings;
@interface MPAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate> @interface MPAppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>
@property (strong) IBOutlet NSWindow *passwordCreatorWindow; @property (strong) IBOutlet NSWindow *passwordCreatorWindow;
@property (strong) IBOutlet NSWindow *welcomeWindow; @property (strong) IBOutlet NSWindow *welcomeWindow;
@property (weak) IBOutlet NSMenuItem *saveMenuItem; @property (weak) IBOutlet NSMenuItem *saveMenuItem;
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
- (IBAction)showPreferences:(id)sender; - (IBAction)showPreferences:(id)sender;
- (IBAction)showPasswordCreator:(id)sender; - (IBAction)showPasswordCreator:(id)sender;
- (IBAction)createNewDatabase:(id)sender; - (IBAction)createNewDatabase:(id)sender;
- (IBAction)openDatabase:(id)sender; - (IBAction)openDatabase:(id)sender;
/**
* Clears the stored key files for any documents.
* @param sender sender of this action
*/
- (IBAction)clearRememberdKeyFiles:(id)sender;
- (NSString *)applicationName; - (NSString *)applicationName;
- (void)lockAllDocuments; - (void)lockAllDocuments;

View File

@@ -36,6 +36,8 @@
#import "MPDocument.h" #import "MPDocument.h"
#import "KPKCompositeKey.h" #import "KPKCompositeKey.h"
NSString *const MPDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDidChangeStoredKeyFilesSettings";
@interface MPAppDelegate () { @interface MPAppDelegate () {
@private @private
MPServerDaemon *serverDaemon; MPServerDaemon *serverDaemon;
@@ -63,9 +65,33 @@
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
- (void)awakeFromNib { #pragma mark Properties
[[self.saveMenuItem menu] setDelegate:self]; - (void)setIsAllowedToStoreKeyFile:(BOOL)isAllowedToStoreKeyFile {
if(_isAllowedToStoreKeyFile != isAllowedToStoreKeyFile) {
_isAllowedToStoreKeyFile = isAllowedToStoreKeyFile;
/* cleanup on disable */
if(!self.isAllowedToStoreKeyFile) {
[self clearRememberdKeyFiles:nil];
} }
/* Inform anyone that might be interested that we can now no longer/ or can use keyfiles */
[[NSNotificationCenter defaultCenter] postNotificationName:MPDidChangeStoredKeyFilesSettings object:self];
}
}
- (void)awakeFromNib {
_isAllowedToStoreKeyFile = NO;
/* Update the at the save menu */
[[self.saveMenuItem menu] setDelegate:self];
/* We want to inform anyone about the changes to keyFile remmebering */
[self bind:@"isAllowedToStoreKeyFile"
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases]
options:nil];
}
#pragma mark -
#pragma mark NSApplicationDelegate
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag {
if(!flag) { if(!flag) {
@@ -123,6 +149,18 @@
return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
} }
#pragma mark -
#pragma mark NSMenuDelegate
- (void)menuNeedsUpdate:(NSMenu *)menu {
if([self.saveMenuItem menu] != menu) {
return; // wrong menu
}
MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
BOOL displayDots = (document.fileURL == nil || !document.compositeKey.hasPasswordOrKeyFile);
NSString *saveTitle = displayDots ? NSLocalizedString(@"SAVE_WITH_DOTS", "") : NSLocalizedString(@"SAVE", "");
[self.saveMenuItem setTitle:saveTitle];
}
#pragma mark - #pragma mark -
#pragma mark Actions #pragma mark Actions
- (void)showPreferences:(id)sender { - (void)showPreferences:(id)sender {
@@ -164,6 +202,12 @@
} }
} }
- (void)clearRememberdKeyFiles:(id)sender {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyRememeberdKeysForDatabases];
}
#pragma mark -
#pragma mark Private Helper
- (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification { - (void)_applicationDidFinishRestoringWindows:(NSNotification *)notification {
NSDocumentController *documentController = [NSDocumentController sharedDocumentController]; NSDocumentController *documentController = [NSDocumentController sharedDocumentController];
NSArray *documents = [documentController documents]; NSArray *documents = [documentController documents];
@@ -206,14 +250,4 @@
return isFileURL; return isFileURL;
} }
#pragma mark NSMenuDelegate
- (void)menuNeedsUpdate:(NSMenu *)menu {
if([self.saveMenuItem menu] != menu) {
return; // wrong menu
}
MPDocument *document = [[NSDocumentController sharedDocumentController] currentDocument];
BOOL displayDots = (document.fileURL == nil || !document.compositeKey.hasPasswordOrKeyFile);
NSString *saveTitle = displayDots ? NSLocalizedString(@"SAVE_WITH_DOTS", "") : NSLocalizedString(@"SAVE", "");
[self.saveMenuItem setTitle:saveTitle];
}
@end @end

View File

@@ -23,8 +23,6 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "KPKVersion.h" #import "KPKVersion.h"
APPKIT_EXTERN NSString *const MPDocumentDidChangeStoredKeyFilesSettings;
APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification; APPKIT_EXTERN NSString *const MPDocumentDidAddGroupNotification;
APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation; APPKIT_EXTERN NSString *const MPDocumentDidRevertNotifiation;
@@ -135,8 +133,19 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
- (void)deleteGroup:(KPKGroup *)group; - (void)deleteGroup:(KPKGroup *)group;
- (void)deleteEntry:(KPKEntry *)entry; - (void)deleteEntry:(KPKEntry *)entry;
#pragma mark Actions
/**
* Empties the Trash group. Removing all Groups and Entries inside. This aciton is not undoable
* @param sender sender
*/
- (IBAction)emptyTrash:(id)sender; - (IBAction)emptyTrash:(id)sender;
/**
* Creates an Entry for a template. We assume the sender is an item, that contains a UUID as representedObject.
*
* @param sender sender, that should respond to representedObject and return an NSUUID for the template to use
*/
- (IBAction)createEntryFromTemplate:(id)sender; - (IBAction)createEntryFromTemplate:(id)sender;
@end @end
@interface MPDocument (Attachments) @interface MPDocument (Attachments)

View File

@@ -21,6 +21,7 @@
// //
#import "MPDocument.h" #import "MPDocument.h"
#import "MPAppDelegate.h"
#import "MPDocumentWindowController.h" #import "MPDocumentWindowController.h"
#import "MPDatabaseVersion.h" #import "MPDatabaseVersion.h"
#import "MPIconHelper.h" #import "MPIconHelper.h"
@@ -41,8 +42,6 @@
#import "KPKTimeInfo.h" #import "KPKTimeInfo.h"
#import "KPKAttribute.h" #import "KPKAttribute.h"
NSString *const MPDocumentDidChangeStoredKeyFilesSettings = @"com.hicknhack.macpass.MPDocumentDidChangeStoredKeyFilesSettings";
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification"; NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation"; NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
@@ -52,11 +51,6 @@ NSString *const MPDocumentDidUnlockDatabaseNotification = @"com.hicknhack.macp
NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey"; NSString *const MPDocumentEntryKey = @"MPDocumentEntryKey";
NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey"; NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey";
typedef NS_ENUM(NSUInteger, MPAlertType) {
MPAlertTypeEmptryTrash,
MPAlertTypeDeleteTrashed
};
@interface MPDocument () { @interface MPDocument () {
@private @private
BOOL _didLockFile; BOOL _didLockFile;
@@ -71,7 +65,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
@property (assign) BOOL readOnly; @property (assign) BOOL readOnly;
@property (strong) NSURL *lockFileURL; @property (strong) NSURL *lockFileURL;
@property (nonatomic, assign) BOOL isAllowedToStoreKeyFile;
@property (strong) IBOutlet NSView *warningView; @property (strong) IBOutlet NSView *warningView;
@property (weak) IBOutlet NSImageView *warningViewImage; @property (weak) IBOutlet NSImageView *warningViewImage;
@@ -118,12 +111,7 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
_encryptedData = nil; _encryptedData = nil;
_didLockFile = NO; _didLockFile = NO;
_readOnly = NO; _readOnly = NO;
_isAllowedToStoreKeyFile = NO;
self.tree = [KPKTree templateTree]; self.tree = [KPKTree templateTree];
[self bind:@"isAllowedToStoreKeyFile"
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases]
options:nil];
} }
return self; return self;
} }
@@ -261,7 +249,8 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
if(isUnlocked) { if(isUnlocked) {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self];
/* Make sure to only store */ /* Make sure to only store */
if(self.compositeKey.hasKeyFile && self.compositeKey.hasPassword && self.isAllowedToStoreKeyFile) { MPAppDelegate *delegate = [NSApp delegate];
if(self.compositeKey.hasKeyFile && self.compositeKey.hasPassword && delegate.isAllowedToStoreKeyFile) {
[self _storeKeyURL:keyFileURL]; [self _storeKeyURL:keyFileURL];
} }
} }
@@ -288,7 +277,8 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
} }
- (NSURL *)suggestedKeyURL { - (NSURL *)suggestedKeyURL {
if(!self.isAllowedToStoreKeyFile) { MPAppDelegate *delegate = [NSApp delegate];
if(!delegate.isAllowedToStoreKeyFile) {
return nil; return nil;
} }
NSDictionary *keysForFiles = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases]; NSDictionary *keysForFiles = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases];
@@ -370,17 +360,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
} }
} }
- (void)setIsAllowedToStoreKeyFile:(BOOL)isAllowedToStoreKeyFile {
if(_isAllowedToStoreKeyFile != isAllowedToStoreKeyFile) {
_isAllowedToStoreKeyFile = isAllowedToStoreKeyFile;
if(!self.isAllowedToStoreKeyFile) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPSettingsKeyRememeberdKeysForDatabases];
}
/* Inform anyone that might be interested that we can now no longer/ or can use keyfiles */
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeStoredKeyFilesSettings object:self];
}
}
#pragma mark Data Accesors #pragma mark Data Accesors
- (KPKEntry *)findEntry:(NSUUID *)uuid { - (KPKEntry *)findEntry:(NSUUID *)uuid {
@@ -518,18 +497,24 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
[[alert buttons][1] setKeyEquivalent:[NSString stringWithFormat:@"%c", 0x1b]]; [[alert buttons][1] setKeyEquivalent:[NSString stringWithFormat:@"%c", 0x1b]];
NSWindow *window = [[self windowControllers][0] window]; NSWindow *window = [[self windowControllers][0] window];
[alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL]; [alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(_emptyTrashAlertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
} }
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { - (void)_emptyTrashAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if(returnCode == NSAlertFirstButtonReturn) { if(returnCode == NSAlertFirstButtonReturn) {
[self _emptyTrash]; [self _emptyTrash];
} }
} }
- (void)createEntryFromTemplate:(id)sender { - (void)createEntryFromTemplate:(id)sender {
NSMenuItem *item = sender; if(![sender respondsToSelector:@selector(representedObject)]) {
NSUUID *entryUUID = [item representedObject]; return; // sender cannot provide usefull data
}
id obj = [sender representedObject];
if([obj isKindOfClass:[NSUUID class]]) {
return; // sender cannot provide NSUUID
}
NSUUID *entryUUID = [sender representedObject];
if(entryUUID) { if(entryUUID) {
KPKEntry *templateEntry = [self findEntry:entryUUID]; KPKEntry *templateEntry = [self findEntry:entryUUID];
if(templateEntry && self.selectedGroup) { if(templateEntry && self.selectedGroup) {
@@ -538,7 +523,6 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
[self.selectedGroup.undoManager setActionName:NSLocalizedString(@"ADD_TREMPLATE_ENTRY", "")]; [self.selectedGroup.undoManager setActionName:NSLocalizedString(@"ADD_TREMPLATE_ENTRY", "")];
} }
} }
return;
} }
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
@@ -585,7 +569,8 @@ typedef NS_ENUM(NSUInteger, MPAlertType) {
if(nil == keyURL) { if(nil == keyURL) {
return; // no URL to store in the first place return; // no URL to store in the first place
} }
NSAssert(self.isAllowedToStoreKeyFile, @"We can only store if we are allowed to do so!"); MPAppDelegate *delegate = [NSApp delegate];
NSAssert(delegate.isAllowedToStoreKeyFile, @"We can only store if we are allowed to do so!");
NSMutableDictionary *keysForFiles = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases] mutableCopy]; NSMutableDictionary *keysForFiles = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyRememeberdKeysForDatabases] mutableCopy];
if(nil == keysForFiles) { if(nil == keysForFiles) {
keysForFiles = [[NSMutableDictionary alloc] initWithCapacity:1]; keysForFiles = [[NSMutableDictionary alloc] initWithCapacity:1];

View File

@@ -7,6 +7,7 @@
// //
#import "MPPasswordInputController.h" #import "MPPasswordInputController.h"
#import "MPAppDelegate.h"
#import "MPDocumentWindowController.h" #import "MPDocumentWindowController.h"
#import "MPDocument.h" #import "MPDocument.h"
#import "MPSettingsHelper.h" #import "MPSettingsHelper.h"
@@ -41,7 +42,7 @@
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) { if(self) {
_enablePassword = YES; _enablePassword = YES;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_selectKeyURL) name:MPDocumentDidChangeStoredKeyFilesSettings object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_selectKeyURL) name:MPDidChangeStoredKeyFilesSettings object:nil];
} }
return self; return self;
} }