diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index f1af43c0..499c1d06 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -135,6 +135,7 @@ 4C5A11FE1708DE8700223D8A /* MPPasswordCreatorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5A11FC1708DE8700223D8A /* MPPasswordCreatorViewController.m */; }; 4C5EF816218CA03F0003C00E /* MPAutotypeParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5EF815218CA03F0003C00E /* MPAutotypeParser.m */; }; 4C5FE9AE17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5FE9AD17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m */; }; + 4C61251C21B94BDD00A93924 /* MPAutotypeExecutionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C61251B21B94BDD00A93924 /* MPAutotypeExecutionContext.m */; }; 4C61EA0316D2FD0800AC519E /* MPOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */; }; 4C61EA0516D2FFE200AC519E /* OutlineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C61EA0416D2FFE200AC519E /* OutlineView.xib */; }; 4C63B8FB17A3154D0091BD72 /* MPContextButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C63B8FA17A3154D0091BD72 /* MPContextButton.m */; }; @@ -549,6 +550,8 @@ 4C5F72851FC4351E00929153 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InspectorView.strings; sourceTree = ""; }; 4C5FE9AC17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSelectedAttachmentTableCellView.h; sourceTree = ""; }; 4C5FE9AD17843CE20001D5A8 /* MPSelectedAttachmentTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSelectedAttachmentTableCellView.m; sourceTree = ""; }; + 4C61251A21B94BDD00A93924 /* MPAutotypeExecutionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPAutotypeExecutionContext.h; sourceTree = ""; }; + 4C61251B21B94BDD00A93924 /* MPAutotypeExecutionContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPAutotypeExecutionContext.m; sourceTree = ""; }; 4C61EA0116D2FD0800AC519E /* MPOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineViewController.h; sourceTree = ""; }; 4C61EA0216D2FD0800AC519E /* MPOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineViewController.m; sourceTree = ""; }; 4C61EA0416D2FFE200AC519E /* OutlineView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OutlineView.xib; sourceTree = ""; }; @@ -1509,6 +1512,8 @@ 4C90757B18A42E7A00E598DA /* Commands */, 4CEE46DB181C301D006BF1E5 /* MPAutotypeDaemon.h */, 4CEE46DC181C301D006BF1E5 /* MPAutotypeDaemon.m */, + 4C61251A21B94BDD00A93924 /* MPAutotypeExecutionContext.h */, + 4C61251B21B94BDD00A93924 /* MPAutotypeExecutionContext.m */, 4CD2B9041849424B0051B395 /* MPAutotypeContext.h */, 4CD2B9051849424B0051B395 /* MPAutotypeContext.m */, 4CA3530918A53CB800839B0F /* MPKeyMapper.h */, @@ -2023,6 +2028,7 @@ 4CE082C31F6FCD2A0034FF56 /* MPCollectionView.m in Sources */, 4C4A100F176286FD00BBF2CA /* MPTableView.m in Sources */, 4CA334CA18AD60D1008A3322 /* MPWindowAssociationsTableViewDelegate.m in Sources */, + 4C61251C21B94BDD00A93924 /* MPAutotypeExecutionContext.m in Sources */, 4C01C2421764D8980016D5D0 /* MPContextMenuHelper.m in Sources */, 4CE296191842A166005F01CE /* MPAutotypePaste.m in Sources */, 4C569D9E17652B0600595B62 /* MPConstants.m in Sources */, diff --git a/MacPass/MPAutotypeDaemon.h b/MacPass/MPAutotypeDaemon.h index 762d001c..32fce461 100644 --- a/MacPass/MPAutotypeDaemon.h +++ b/MacPass/MPAutotypeDaemon.h @@ -25,12 +25,13 @@ @class DDHotKey; @class KPKEntry; @class MPAutotypeContext; - +@class MPAutotypeExecutionContext; /** * The autotype daemon is responsible for registering the global hotkey and to perform any autotype actions */ @interface MPAutotypeDaemon : NSObject +@property (strong, readonly) MPAutotypeExecutionContext *executionContext; @property (strong) IBOutlet NSWindow *matchSelectionWindow; @property (weak) IBOutlet NSPopUpButton *matchSelectionButton; @property (readonly, strong) DDHotKey *registredHotKey; diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index 677c2486..448527a2 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -25,6 +25,7 @@ #import "MPDocumentWindowController.h" #import "MPAutotypeCommand.h" #import "MPAutotypeContext.h" +#import "MPAutotypeExecutionContext.h" #import "MPAutotypePaste.h" #import "MPPasteBoardController.h" #import "MPSettingsHelper.h" @@ -52,6 +53,7 @@ NSString *const kMPProcessIdentifierKey = @"kMPProcessIdentifierKey"; @property (copy) NSString *targetWindowTitle; // The title of the window that we are targeting @property (strong) NSRunningApplication *previousApplication; // The application that was active before we got invoked @property (assign) NSTimeInterval userActionRequested; +@property (strong, readwrite) MPAutotypeExecutionContext *executionContext; @end @@ -312,18 +314,20 @@ static MPAutotypeDaemon *_sharedInstance; if(nil == context) { return; // No context to work with } + if([self _orderApplicationToFront:self.targetPID]) { /* Sleep a bit after the app was activated */ /* TODO - we can use a saver way and use a notification to check if the app actally was activated */ usleep(1 * NSEC_PER_MSEC); } - + self.executionContext = [[MPAutotypeExecutionContext alloc] initWithTargetPid:self.targetPID]; for(MPAutotypeCommand *command in [MPAutotypeCommand commandsForContext:context]) { /* dispatch commands to main thread since most of them translate key events which is disallowed on background thread */ dispatch_async(dispatch_get_main_queue(), ^{ [command execute]; }); } + self.executionContext = nil; } #pragma mark - diff --git a/MacPass/MPAutotypeExecutionContext.h b/MacPass/MPAutotypeExecutionContext.h new file mode 100644 index 00000000..c63f4372 --- /dev/null +++ b/MacPass/MPAutotypeExecutionContext.h @@ -0,0 +1,22 @@ +// +// MPAutotypeExectutionContext.h +// MacPass +// +// Created by Michael Starke on 06.12.18. +// Copyright © 2018 HicknHack Software GmbH. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MPAutotypeExecutionContext : NSObject + +@property (readonly) pid_t targetPid; + +- (instancetype)initWithTargetPid:(pid_t)pid NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MacPass/MPAutotypeExecutionContext.m b/MacPass/MPAutotypeExecutionContext.m new file mode 100644 index 00000000..2909ec65 --- /dev/null +++ b/MacPass/MPAutotypeExecutionContext.m @@ -0,0 +1,27 @@ +// +// MPAutotypeExectutionContext.m +// MacPass +// +// Created by Michael Starke on 06.12.18. +// Copyright © 2018 HicknHack Software GmbH. All rights reserved. +// + +#import "MPAutotypeExecutionContext.h" + +@interface MPAutotypeExecutionContext () + +@property (readwrite) pid_t targetPid; + +@end + +@implementation MPAutotypeExecutionContext + +- (instancetype)initWithTargetPid:(pid_t)pid { + self = [super init]; + if(self) { + self.targetPid = pid; + } + return self; +} + +@end diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index 29f46d2f..03824982 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -78,6 +78,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey; @property (nonatomic, strong, readonly) KPKCompositeKey *compositeKey; @property (assign, readonly, getter = isReadOnly) BOOL readOnly; +@property (atomic, assign) BOOL shouldSaveOnLock; @property (nonatomic, readonly, assign) KPKDatabaseFormat formatForFileType; /* @@ -162,6 +163,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey; - (void)deleteNode:(KPKNode *)node; - (void)duplicateEntryWithOptions:(KPKCopyOptions)options; + #pragma mark Actions /** * Empties the Trash group. Removing all Groups and Entries inside. This action is not undo-able diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index dc862291..99f46795 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -61,6 +61,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou @interface MPDocument () { @private BOOL _didLockFile; + BOOL _shoudlSaveOnLock; } @property (nonatomic, assign) NSUInteger unlockCount; @@ -124,6 +125,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou _didLockFile = NO; _readOnly = NO; _lockedForFileChange = NO; + self.shouldSaveOnLock = NO; } return self; } @@ -173,8 +175,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou - (NSData *)dataOfType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError { if(self.encrypted) { - NSAssert(!self.encrypted, @"%@ should not be called on locked databases!", NSStringFromSelector(_cmd)); - //return self.encryptedData; + NSLog(@"%@ should not be called on locked databases!", NSStringFromSelector(_cmd)); + return self.encryptedData; } if(!self.compositeKey.hasPasswordOrKeyFile) { if(outError != NULL) { @@ -324,6 +326,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou [self mergeWithContentsFromURL:self.fileURL key:self.compositeKey]; } else if(strategy == MPFileChangeStrategyUseOther) { + /* dispatch? */ + [self revertToContentsOfURL:self.fileURL ofType:self.fileType error:nil]; } // else do nothing! @@ -389,7 +393,6 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou if(otherTree) { [self.tree synchronizeWithTree:otherTree mode:KPKSynchronizationModeSynchronize options:options]; /* the key might have changed so update ours! */ - //self.compositeKey = key; [self updateChangeCount:NSChangeDone]; NSUserNotification *notification = [[NSUserNotification alloc] init]; notification.title = NSApp.applicationName; @@ -432,7 +435,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou #pragma mark Lock/Unlock/Decrypt - (void)lockDatabase:(id)sender { /* - [self saveDocument] is enqued so that dataOfType is called too late to actually save teh database. + [self saveDocument] is enqued so that dataOfType is called too late to actually save the database. hence we need to get the ok from the NSDocument about the save, otherwise the lock fails! */ // only lock if we do not have user interaction that cannot be dismissed! @@ -440,8 +443,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou for(NSWindow *sheet in self.windowForSheet.sheets) { [self.windowForSheet endSheet:sheet]; } - if(self.documentEdited) { + if(self.documentEdited || self.shouldSaveOnLock) { [self saveDocumentWithDelegate:self didSaveSelector:@selector(_lockDatabaseForDocument:didSave:contextInfo:) contextInfo:NULL]; + self.shouldSaveOnLock = NO; } else { [self _lockDatabaseForDocument:self didSave:YES contextInfo:NULL]; @@ -455,7 +459,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou return; // wrong parameters } if(!didSave) { - return; // not saved! + return; // not saved we need to be sure it happend! } /* FIXME: User feedback is ignored */ [self exitSearch:self]; diff --git a/MacPass/MPKeyTyper.m b/MacPass/MPKeyTyper.m index ae3f859e..be5febb4 100644 --- a/MacPass/MPKeyTyper.m +++ b/MacPass/MPKeyTyper.m @@ -8,6 +8,8 @@ #import "MPKeyTyper.h" #import "MPKeyMapper.h" +#import "MPAutotypeDaemon.h" +#import "MPAutotypeExecutionContext.h" @implementation MPKeyTyper @@ -53,7 +55,6 @@ /* TODO: Evaluate postToPid */ usleep(0.05 * NSEC_PER_MSEC); CGEventPost(kCGHIDEventTap, releaseKey); - /* TODO: Evaluate postToPid */ CFRelease(pressKey); CFRelease(releaseKey); diff --git a/MacPass/MPOutlineViewController.m b/MacPass/MPOutlineViewController.m index bac842c2..0c651275 100644 --- a/MacPass/MPOutlineViewController.m +++ b/MacPass/MPOutlineViewController.m @@ -316,7 +316,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell"; document.tree.metaData.lastSelectedGroup = (groups.count == 1 ? groups.firstObject.uuid : [NSUUID kpk_nullUUID]); NSUUID *newVlaue = document.tree.metaData.lastSelectedGroup; if(![oldValue isEqual:newVlaue]) { - [document updateChangeCount:NSChangeDone|NSChangeDiscardable]; + document.shouldSaveOnLock = YES; } } document.selectedGroups = groups;