Using custom supressable dialog to check for autotype capabilities. Added notification when user performs autotype on disabled systems

This commit is contained in:
Michael Starke
2018-11-12 17:46:05 +01:00
parent 2d27fcbbb0
commit 04ffcab15b
9 changed files with 97 additions and 14 deletions

View File

@@ -25,14 +25,14 @@
@interface DDHotKey (MPKeydata)
@property (readonly, copy) NSData *keyData;
@property (readonly, copy, class) NSData *defaultHotKeyData;
/**
Use this method to retrieve the data, since deallocation of a hotkey unregisters it, this could yield unwanted behaviour!
@return data for the default hot key.
*/
+ (NSData *)hotKeyDataWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags;
+ (NSData *)defaultHotKeyData;
+ (instancetype)defaultHotKey;
+ (instancetype)defaultHotKeyWithTask:(DDHotKeyTask)task;
+ (instancetype)hotKeyWithKeyData:(NSData *)data task:(DDHotKeyTask)task;

View File

@@ -40,6 +40,7 @@
- (instancetype)init NS_UNAVAILABLE;
- (void)checkForAccessibiltyPermissions;
- (void)openAccessibiltyPreferences;
- (void)performAutotypeForEntry:(KPKEntry *)entry;
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence;

View File

@@ -134,13 +134,47 @@ static MPAutotypeDaemon *_sharedInstance;
}
- (void)checkForAccessibiltyPermissions {
if(@available(macOS 10.14, *)) {
CFStringRef keys[] = { kAXTrustedCheckOptionPrompt };
CFBooleanRef values[] = { kCFBooleanTrue };
CFDictionaryRef dictRef = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
AXIsProcessTrustedWithOptions(dictRef);
CFRelease(dictRef);
if(!self.enabled) {
return;
}
BOOL hideAlert = NO;
if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning]) {
hideAlert = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning];
}
if(hideAlert || self.autotypeSupported) {
return;
}
else {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSWarningAlertStyle;
alert.messageText = NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_MESSAGE_TEXT", @"Alert message displayed when Autotype performs self check and lacks accessibilty permissions");
alert.informativeText = NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_INFORMATIVE_TEXT", @"Alert informative text displayed when Autotype performs self check and lacks accessibilty permissions");
alert.showsSuppressionButton = YES;
alert.suppressionButton.title = NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_SUPPRESS_WARNING", @"Checkbox in dialog to set the selection as default file change strategy!");
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OK", @"Button in dialog to leave autotype disabled and continiue!")];
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OPEN_PREFERENCES", @"Button in dialog to open accessibilty preferences pane!")];
NSWindow *window = NSDocumentController.sharedDocumentController.currentDocument.windowForSheet;
[alert beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
BOOL suppressWarning = (alert.suppressionButton.state == NSOnState);
[NSUserDefaults.standardUserDefaults setBool:suppressWarning forKey:kMPSettingsKeyAutotypeHideAccessibiltyWarning];
switch(returnCode) {
case NSAlertFirstButtonReturn: {
/* ok, ignore */
break;
}
case NSAlertSecondButtonReturn:
/* open prefs */
[self openAccessibiltyPreferences];
break;
default:
break;
}
}];
}
}
- (void)openAccessibiltyPreferences {
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"]];
}
#pragma mark -
@@ -180,7 +214,17 @@ static MPAutotypeDaemon *_sharedInstance;
#pragma mark Autotype Execution
- (void)_performAutotypeForEntry:(KPKEntry *)entryOrNil {
NSInteger pid = [NSProcessInfo processInfo].processIdentifier;
if(!self.autotypeSupported) {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = NSApp.applicationName;
notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MACPASS_HAS_NO_ACCESSIBILTY_PERMISSIONS", "Notification: Autotype failed, MacPass has no permission to send key strokes");
notification.actionButtonTitle = NSLocalizedString(@"OPEN_PREFERENCES", "Action button in Notification to show the Accessibilty preferences");
notification.userInfo = @{ MPUserNotificationTypeKey: MPUserNotificationTypeShowAccessibiltyPreferences };
notification.showsButtons = YES;
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
return;
}
NSInteger pid = NSProcessInfo.processInfo.processIdentifier;
if(self.targetPID == pid) {
return; // We do not perform Autotype on ourselves
}

View File

@@ -116,6 +116,7 @@
[self.autotypeStackView setVisibilityPriority:NSStackViewVisibilityPriorityMustHold forView:self.openPreferencesButton];
}
/*
NSArray <NSControl *> *controls = @[ self.enableGlobalAutotypeCheckBox,
self.hotKeyTextField,
self.matchTitleCheckBox,
@@ -126,10 +127,10 @@
for(NSControl *control in controls) {
control.enabled = hasAutotypeSupport;
}
*/
}
- (void)openAccessibiltyPreferences:(id)sender {
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"]];
[MPAutotypeDaemon.defaultDaemon openAccessibiltyPreferences];
}
@end

View File

@@ -50,8 +50,8 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideUsername;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHidePassword;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideNotes;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideURL;
/* Document/Key Location store */
/* Document/Key Location store */
APPKIT_EXTERN NSString *const kMPSettingsKeyLastDatabasePath; // Path to the last opened Database. Workaround if users have disabled the feature in the OS
APPKIT_EXTERN NSString *const kMPSettingsKeyRememeberdKeysForDatabases; // NSDictionary of all db file urls and the corresponding key file url
APPKIT_EXTERN NSString *const kMPSettingsKeyRememberKeyFilesForDatabases; // YES if key files should be remembers
@@ -65,6 +65,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTitle; //
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchURL; // Autotype lookup includes entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchHost; // Autotype lookup includes host part of entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTags; // Autotype lookup includes tags for entries
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeHideAccessibiltyWarning; // Do not show an alert, when MacPass has no support for Autotype
/* Search */
APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterContext;

View File

@@ -56,6 +56,7 @@ NSString *const kMPSettingsKeyAutotypeMatchTitle = @"Autoty
NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL";
NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost";
NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags";
NSString *const kMPSettingsKeyAutotypeHideAccessibiltyWarning = @"AutotypeHideAccessibiltyWarning";
NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext";

View File

@@ -25,6 +25,7 @@
FOUNDATION_EXTERN NSString *const MPUserNotificationTypeKey;
FOUNDATION_EXTERN NSString *const MPUserNotificationTypeAutotypeFeedback;
FOUNDATION_EXTERN NSString *const MPUserNotificationTypeAutotypeOpenDocumentRequest;
FOUNDATION_EXTERN NSString *const MPUserNotificationTypeShowAccessibiltyPreferences;
@interface MPUserNotificationCenterDelegate : NSObject <NSUserNotificationCenterDelegate>

View File

@@ -22,10 +22,12 @@
#import "MPUserNotificationCenterDelegate.h"
#import "MPDocumentController.h"
#import "MPAutotypeDaemon.h"
NSString *const MPUserNotificationTypeKey = @"MPUserNotificationTypeKey";
NSString *const MPUserNotificationTypeAutotypeFeedback = @"MPUserNotificationTypeAutotypeFeedback";
NSString *const MPUserNotificationTypeAutotypeOpenDocumentRequest = @"MPUserNotificationTypeAutotypeOpenDocumentRequest";
NSString *const MPUserNotificationTypeShowAccessibiltyPreferences = @"MPUserNotificationTypeShowAccessibiltyPreferences";
@implementation MPUserNotificationCenterDelegate
@@ -39,13 +41,24 @@ NSString *const MPUserNotificationTypeAutotypeOpenDocumentRequest = @"MPUserNoti
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
if([userInfo[MPUserNotificationTypeKey] isEqualToString:MPUserNotificationTypeAutotypeOpenDocumentRequest]) {
NSString *notificationType = userInfo[MPUserNotificationTypeKey];
if([notificationType isEqualToString:MPUserNotificationTypeAutotypeOpenDocumentRequest]) {
[((MPDocumentController*)NSDocumentController.sharedDocumentController) reopenLastDocument];
}
else if([notificationType isEqualToString:MPUserNotificationTypeShowAccessibiltyPreferences]) {
[MPAutotypeDaemon.defaultDaemon openAccessibiltyPreferences];
}
}
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
return [notification.userInfo[MPUserNotificationTypeKey] isEqualToString:MPUserNotificationTypeAutotypeFeedback];
NSString *notificationType = notification.userInfo[MPUserNotificationTypeKey];
if([notificationType isEqualToString:MPUserNotificationTypeAutotypeFeedback]) {
return YES;
}
if([notificationType isEqualToString:MPUserNotificationTypeShowAccessibiltyPreferences]) {
return YES;
}
return NO;
}

View File

@@ -31,6 +31,21 @@
/* Action to add an entry via template */
"ADD_TREMPLATE_ENTRY" = "Create Template Entry";
/* Button in dialog to leave autotype disabled and continiue! */
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OK" = "Keep Autotype disabled.";
/* Button in dialog to open accessibilty preferences pane! */
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_BUTTON_OPEN_PREFERENCES" = "Open Accessibilty Preferences…";
/* Alert informative text displayed when Autotype performs self check and lacks accessibilty permissions */
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_INFORMATIVE_TEXT" = "The system prevents MacPass from sending key strokes to other Applications. To enable Autotype please grant MacPass Accessibilty rights in the privacy preferences.";
/* Alert message displayed when Autotype performs self check and lacks accessibilty permissions */
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_MESSAGE_TEXT" = "MacPass cannot perform Autotype";
/* Checkbox in dialog to set the selection as default file change strategy! */
"ALERT_AUTOTYPE_MISSING_ACCESSIBILTY_PERMISSIONS_SUPPRESS_WARNING" = "Do not show this warning again.";
/* Alert informative text when plugins or their settings change and require a restart */
"ALERT_INFORMATIVE_TEXT_PLUGINS_CHANGED_SUGGEST_RESTART" = "Changes to plugins and global plugin settings take only effect after restart. Restart MacPass now?";
@@ -80,6 +95,9 @@
/* Disable autotype menu item */
"AUTOTYPE_NO" = "Disable Autotype";
/* Notification: Autotype failed, MacPass has no permission to send key strokes */
"AUTOTYPE_NOTIFICATION_MACPASS_HAS_NO_ACCESSIBILTY_PERMISSIONS" = "Autotype disabled because of missing accessibilty access.";
/* Notification: Autotype failed, no documents are open */
"AUTOTYPE_OVERLAY_NO_DOCUMENTS" = "Please open a database file to use Global Autotype!";
@@ -408,6 +426,9 @@
/* Action button in Notification to open a document */
"OPEN_DOCUMENT" = "Open Document";
/* Action button in Notification to show the Accessibilty preferences */
"OPEN_PREFERENCES" = "Open Accessiblity Preferences…";
/* Menu item to open the URL with the default application */
"OPEN_URL" = "Open URL";