|
13 | 13 | #import <Photos/Photos.h> |
14 | 14 | #import <Speech/Speech.h> |
15 | 15 | #import <StoreKit/StoreKit.h> |
| 16 | +#import <UserNotifications/UserNotifications.h> |
16 | 17 | #import <pwd.h> |
17 | 18 |
|
18 | 19 | /***** HELPER FUNCTIONS *****/ |
|
22 | 23 | const std::string kRestricted{"restricted"}; |
23 | 24 | const std::string kNotDetermined{"not determined"}; |
24 | 25 | const std::string kLimited{"limited"}; |
| 26 | +const std::string kProvisional{"provisional"}; |
25 | 27 |
|
26 | 28 | // Check if a bundle ID is valid (i.e., corresponds to an installed app) |
27 | 29 | bool IsValidBundleID(NSString *bundleID) { |
@@ -104,6 +106,19 @@ IOHIDRequestType GetInputMonitoringAccessType(const std::string &type) { |
104 | 106 | } |
105 | 107 | } |
106 | 108 |
|
| 109 | +const std::string &StringFromNotificationStatus(UNAuthorizationStatus status) { |
| 110 | + switch (status) { |
| 111 | + case UNAuthorizationStatusAuthorized: |
| 112 | + return kAuthorized; |
| 113 | + case UNAuthorizationStatusDenied: |
| 114 | + return kDenied; |
| 115 | + case UNAuthorizationStatusProvisional: |
| 116 | + return kProvisional; |
| 117 | + default: |
| 118 | + return kNotDetermined; |
| 119 | + } |
| 120 | +} |
| 121 | + |
107 | 122 | std::string StringFromSpeechRecognitionStatus( |
108 | 123 | SFSpeechRecognizerAuthorizationStatus status) { |
109 | 124 | switch (status) { |
@@ -376,6 +391,30 @@ bool HasOpenSystemPreferencesDialog() { |
376 | 391 | return StringFromSpeechRecognitionStatus(status); |
377 | 392 | } |
378 | 393 |
|
| 394 | +// Returns a status indicating whether the user has authorized |
| 395 | +// Notifications access. |
| 396 | +std::string NotificationAuthStatus() { |
| 397 | + NSURL *bundle_url = [[NSBundle mainBundle] bundleURL]; |
| 398 | + if (!IsValidBundleID([bundle_url path])) { |
| 399 | + return kNotDetermined; |
| 400 | + } |
| 401 | + |
| 402 | + __block std::string ret = "not determined"; |
| 403 | + dispatch_group_t g = dispatch_group_create(); |
| 404 | + dispatch_group_enter(g); |
| 405 | + |
| 406 | + UNUserNotificationCenter *center = |
| 407 | + [UNUserNotificationCenter currentNotificationCenter]; |
| 408 | + [center getNotificationSettingsWithCompletionHandler:^( |
| 409 | + UNNotificationSettings *settings) { |
| 410 | + ret = StringFromNotificationStatus(settings.authorizationStatus); |
| 411 | + dispatch_group_leave(g); |
| 412 | + }]; |
| 413 | + |
| 414 | + dispatch_group_wait(g, DISPATCH_TIME_FOREVER); |
| 415 | + return ret; |
| 416 | +} |
| 417 | + |
379 | 418 | // Returns a status indicating whether the user has authorized location |
380 | 419 | // access. |
381 | 420 | std::string LocationAuthStatus() { |
@@ -444,6 +483,8 @@ bool HasOpenSystemPreferencesDialog() { |
444 | 483 | auth_status = MusicLibraryAuthStatus(); |
445 | 484 | } else if (type == "input-monitoring") { |
446 | 485 | auth_status = InputMonitoringAuthStatus(); |
| 486 | + } else if (type == "notifications") { |
| 487 | + auth_status = NotificationAuthStatus(); |
447 | 488 | } |
448 | 489 |
|
449 | 490 | return Napi::Value::From(env, auth_status); |
|
0 commit comments