@@ -44,8 +44,7 @@ PHAccessLevel GetPHAccessLevel(const std::string &type)
44
44
return type == " read-write" ? PHAccessLevelReadWrite : PHAccessLevelAddOnly;
45
45
}
46
46
47
- IOHIDRequestType GetInputMonitoringAccessType (const std::string &type)
48
- API_AVAILABLE(macosx(10.15 )) {
47
+ IOHIDRequestType GetInputMonitoringAccessType (const std::string &type) {
49
48
return type == " post" ? kIOHIDRequestTypePostEvent
50
49
: kIOHIDRequestTypeListenEvent ;
51
50
}
@@ -89,9 +88,8 @@ IOHIDRequestType GetInputMonitoringAccessType(const std::string &type)
89
88
}
90
89
}
91
90
92
- std::string
93
- StringFromSpeechRecognitionStatus (SFSpeechRecognizerAuthorizationStatus status)
94
- API_AVAILABLE(macosx(10.15 )) {
91
+ std::string StringFromSpeechRecognitionStatus (
92
+ SFSpeechRecognizerAuthorizationStatus status) {
95
93
switch (status) {
96
94
case SFSpeechRecognizerAuthorizationStatusAuthorized:
97
95
return kAuthorized ;
@@ -204,65 +202,53 @@ bool HasOpenSystemPreferencesDialog() {
204
202
205
203
// Returns a status indicating whether the user has authorized Bluetooth access.
206
204
std::string BluetoothAuthStatus () {
207
- if (@available (macOS 10.15 , *)) {
208
- switch ([CBCentralManager authorization ]) {
209
- case CBManagerAuthorizationAllowedAlways:
210
- return kAuthorized ;
211
- case CBManagerAuthorizationDenied:
212
- return kDenied ;
213
- case CBManagerAuthorizationRestricted:
214
- return kRestricted ;
215
- default :
216
- return kNotDetermined ;
217
- }
205
+ switch ([CBCentralManager authorization ]) {
206
+ case CBManagerAuthorizationAllowedAlways:
207
+ return kAuthorized ;
208
+ case CBManagerAuthorizationDenied:
209
+ return kDenied ;
210
+ case CBManagerAuthorizationRestricted:
211
+ return kRestricted ;
212
+ default :
213
+ return kNotDetermined ;
218
214
}
219
-
220
- return kAuthorized ;
221
215
}
222
216
223
217
// Returns a status indicating whether the user has authorized
224
218
// input monitoring access.
225
219
std::string InputMonitoringAuthStatus () {
226
- if (@available (macOS 10.15 , *)) {
227
- switch (IOHIDCheckAccess (kIOHIDRequestTypeListenEvent )) {
228
- case kIOHIDAccessTypeGranted :
229
- return kAuthorized ;
230
- case kIOHIDAccessTypeDenied :
231
- return kDenied ;
232
- default :
233
- return kNotDetermined ;
234
- }
220
+ switch (IOHIDCheckAccess (kIOHIDRequestTypeListenEvent )) {
221
+ case kIOHIDAccessTypeGranted :
222
+ return kAuthorized ;
223
+ case kIOHIDAccessTypeDenied :
224
+ return kDenied ;
225
+ default :
226
+ return kNotDetermined ;
235
227
}
236
-
237
- return kAuthorized ;
238
228
}
239
229
240
230
// Returns a status indicating whether the user has authorized Apple Events.
241
231
std::string AppleEventsAuthStatus (Napi::Env env) {
242
- if (@available (macOS 10.14 , *)) {
243
- AEDesc target_app = {typeNull, NULL };
244
- OSStatus status = AECreateDesc (typeApplicationBundleID, " com.apple.finder" ,
245
- strlen (" com.apple.finder" ), &target_app);
246
- if (status != noErr) {
247
- std::string err_msg = " Failed to query for Apple Events access" ;
248
- Napi::Error::New (env, err_msg).ThrowAsJavaScriptException ();
249
- return kNotDetermined ;
250
- }
251
-
252
- status = AEDeterminePermissionToAutomateTarget (&target_app, kCoreEventClass ,
253
- kAEOpenDocuments , false );
232
+ AEDesc target_app = {typeNull, NULL };
233
+ OSStatus status = AECreateDesc (typeApplicationBundleID, " com.apple.finder" ,
234
+ strlen (" com.apple.finder" ), &target_app);
235
+ if (status != noErr) {
236
+ std::string err_msg = " Failed to query for Apple Events access" ;
237
+ Napi::Error::New (env, err_msg).ThrowAsJavaScriptException ();
238
+ return kNotDetermined ;
239
+ }
254
240
255
- AEDisposeDesc (&target_app);
241
+ status = AEDeterminePermissionToAutomateTarget (&target_app, kCoreEventClass ,
242
+ kAEOpenDocuments , false );
256
243
257
- // User prompt has not yet been shown.
258
- if (status == errAEEventWouldRequireUserConsent) {
259
- return kNotDetermined ;
260
- }
244
+ AEDisposeDesc (&target_app);
261
245
262
- return status == noErr ? kAuthorized : kDenied ;
246
+ // User prompt has not yet been shown.
247
+ if (status == errAEEventWouldRequireUserConsent) {
248
+ return kNotDetermined ;
263
249
}
264
250
265
- return kAuthorized ;
251
+ return status == noErr ? kAuthorized : kDenied ;
266
252
}
267
253
268
254
// Returns a status indicating whether the user has authorized Apple Music
@@ -306,14 +292,10 @@ bool HasOpenSystemPreferencesDialog() {
306
292
[home_folder
307
293
stringByAppendingPathComponent:
308
294
@" /Library/Application Support/com.apple.TCC/TCC.db" ],
309
- @" /Library/Preferences/com.apple.TimeMachine.plist" , nil ];
310
-
311
- if (@available (macOS 10.15 , *)) {
312
- [files addObject: [home_folder
313
- stringByAppendingPathComponent:
314
- @" Library/S]l;l;khb acddeffrfr55r4ewwe22q11 Z "
315
- @" ,Kmmjmn bn;pp9iuyyuuujn afari/CloudTabs.db" ]];
316
- }
295
+ @" /Library/Preferences/com.apple.TimeMachine.plist" ,
296
+ [home_folder
297
+ stringByAppendingPathComponent: @" Library/Safari/CloudTabs.db" ],
298
+ nil ];
317
299
318
300
std::string auth_status = kNotDetermined ;
319
301
for (NSString *file in files) {
@@ -335,7 +317,7 @@ bool HasOpenSystemPreferencesDialog() {
335
317
std::string auth_status = kNotDetermined ;
336
318
if (@available (macOS 11.0 , *)) {
337
319
auth_status = CGPreflightScreenCaptureAccess () ? kAuthorized : kDenied ;
338
- } else if (@ available (macOS 10.15 , *)) {
320
+ } else {
339
321
auth_status = kDenied ;
340
322
NSRunningApplication *runningApplication =
341
323
NSRunningApplication .currentApplication ;
@@ -371,8 +353,6 @@ bool HasOpenSystemPreferencesDialog() {
371
353
}
372
354
}
373
355
CFRelease (windowList);
374
- } else {
375
- auth_status = kAuthorized ;
376
356
}
377
357
378
358
return auth_status;
@@ -381,35 +361,27 @@ bool HasOpenSystemPreferencesDialog() {
381
361
// Returns a status indicating whether the user has authorized
382
362
// Camera/Microphone access.
383
363
std::string MediaAuthStatus (const std::string &type) {
384
- if (@available (macOS 10.14 , *)) {
385
- AVMediaType media_type =
386
- (type == " microphone" ) ? AVMediaTypeAudio : AVMediaTypeVideo;
387
-
388
- switch ([AVCaptureDevice authorizationStatusForMediaType: media_type]) {
389
- case AVAuthorizationStatusAuthorized:
390
- return kAuthorized ;
391
- case AVAuthorizationStatusDenied:
392
- return kDenied ;
393
- case AVAuthorizationStatusRestricted:
394
- return kRestricted ;
395
- default :
396
- return kNotDetermined ;
397
- }
398
- }
364
+ AVMediaType media_type =
365
+ (type == " microphone" ) ? AVMediaTypeAudio : AVMediaTypeVideo;
399
366
400
- return kAuthorized ;
367
+ switch ([AVCaptureDevice authorizationStatusForMediaType: media_type]) {
368
+ case AVAuthorizationStatusAuthorized:
369
+ return kAuthorized ;
370
+ case AVAuthorizationStatusDenied:
371
+ return kDenied ;
372
+ case AVAuthorizationStatusRestricted:
373
+ return kRestricted ;
374
+ default :
375
+ return kNotDetermined ;
376
+ }
401
377
}
402
378
403
379
// Returns a status indicating whether the user has authorized speech
404
380
// recognition access.
405
381
std::string SpeechRecognitionAuthStatus () {
406
- if (@available (macOS 10.15 , *)) {
407
- SFSpeechRecognizerAuthorizationStatus status =
408
- [SFSpeechRecognizer authorizationStatus ];
409
- return StringFromSpeechRecognitionStatus (status);
410
- }
411
-
412
- return kAuthorized ;
382
+ SFSpeechRecognizerAuthorizationStatus status =
383
+ [SFSpeechRecognizer authorizationStatus ];
384
+ return StringFromSpeechRecognitionStatus (status);
413
385
}
414
386
415
387
// Returns a status indicating whether the user has authorized location
@@ -610,27 +582,21 @@ void AskForFullDiskAccess(const Napi::CallbackInfo &info) {
610
582
deferred.Resolve (Napi::String::New (env, status));
611
583
};
612
584
613
- if (@available (macOS 10.14 , *)) {
614
- std::string auth_status = MediaAuthStatus (" camera" );
585
+ std::string auth_status = MediaAuthStatus (" camera" );
615
586
616
- if (auth_status == kNotDetermined ) {
617
- [AVCaptureDevice
618
- requestAccessForMediaType: AVMediaTypeVideo
619
- completionHandler: ^(BOOL granted) {
620
- tsfn.BlockingCall (granted ? " authorized" : " denied" ,
621
- callback);
622
- tsfn.Release ();
623
- }];
624
- } else {
625
- if (auth_status == kDenied )
626
- OpenPrefPane (" Privacy_Camera" );
627
-
628
- tsfn.Release ();
629
- deferred.Resolve (Napi::String::New (env, auth_status));
630
- }
587
+ if (auth_status == kNotDetermined ) {
588
+ [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo
589
+ completionHandler: ^(BOOL granted) {
590
+ tsfn.BlockingCall (
591
+ granted ? " authorized" : " denied" , callback);
592
+ tsfn.Release ();
593
+ }];
631
594
} else {
595
+ if (auth_status == kDenied )
596
+ OpenPrefPane (" Privacy_Camera" );
597
+
632
598
tsfn.Release ();
633
- deferred.Resolve (Napi::String::New (env, kAuthorized ));
599
+ deferred.Resolve (Napi::String::New (env, auth_status ));
634
600
}
635
601
636
602
return deferred.Promise ();
@@ -647,26 +613,21 @@ void AskForFullDiskAccess(const Napi::CallbackInfo &info) {
647
613
deferred.Resolve (Napi::String::New (env, status));
648
614
};
649
615
650
- if (@available (macOS 10.15 , *)) {
651
- std::string auth_status = SpeechRecognitionAuthStatus ();
652
-
653
- if (auth_status == kNotDetermined ) {
654
- [SFSpeechRecognizer
655
- requestAuthorization: ^(SFSpeechRecognizerAuthorizationStatus status) {
656
- std::string auth_result = StringFromSpeechRecognitionStatus (status);
657
- tsfn.BlockingCall (auth_result.c_str (), callback);
658
- tsfn.Release ();
659
- }];
660
- } else {
661
- if (auth_status == kDenied )
662
- OpenPrefPane (" Privacy_SpeechRecognition" );
616
+ std::string auth_status = SpeechRecognitionAuthStatus ();
663
617
664
- tsfn.Release ();
665
- deferred.Resolve (Napi::String::New (env, auth_status));
666
- }
618
+ if (auth_status == kNotDetermined ) {
619
+ [SFSpeechRecognizer
620
+ requestAuthorization: ^(SFSpeechRecognizerAuthorizationStatus status) {
621
+ std::string auth_result = StringFromSpeechRecognitionStatus (status);
622
+ tsfn.BlockingCall (auth_result.c_str (), callback);
623
+ tsfn.Release ();
624
+ }];
667
625
} else {
626
+ if (auth_status == kDenied )
627
+ OpenPrefPane (" Privacy_SpeechRecognition" );
628
+
668
629
tsfn.Release ();
669
- deferred.Resolve (Napi::String::New (env, kAuthorized ));
630
+ deferred.Resolve (Napi::String::New (env, auth_status ));
670
631
}
671
632
672
633
return deferred.Promise ();
@@ -726,27 +687,21 @@ void AskForFullDiskAccess(const Napi::CallbackInfo &info) {
726
687
deferred.Resolve (Napi::String::New (env, status));
727
688
};
728
689
729
- if (@available (macOS 10.14 , *)) {
730
- std::string auth_status = MediaAuthStatus (" microphone" );
731
-
732
- if (auth_status == kNotDetermined ) {
733
- [AVCaptureDevice
734
- requestAccessForMediaType: AVMediaTypeAudio
735
- completionHandler: ^(BOOL granted) {
736
- tsfn.BlockingCall (granted ? " authorized" : " denied" ,
737
- callback);
738
- tsfn.Release ();
739
- }];
740
- } else {
741
- if (auth_status == kDenied )
742
- OpenPrefPane (" Privacy_Microphone" );
690
+ std::string auth_status = MediaAuthStatus (" microphone" );
743
691
744
- tsfn.Release ();
745
- deferred.Resolve (Napi::String::New (env, auth_status));
746
- }
692
+ if (auth_status == kNotDetermined ) {
693
+ [AVCaptureDevice requestAccessForMediaType: AVMediaTypeAudio
694
+ completionHandler: ^(BOOL granted) {
695
+ tsfn.BlockingCall (
696
+ granted ? " authorized" : " denied" , callback);
697
+ tsfn.Release ();
698
+ }];
747
699
} else {
700
+ if (auth_status == kDenied )
701
+ OpenPrefPane (" Privacy_Microphone" );
702
+
748
703
tsfn.Release ();
749
- deferred.Resolve (Napi::String::New (env, kAuthorized ));
704
+ deferred.Resolve (Napi::String::New (env, auth_status ));
750
705
}
751
706
752
707
return deferred.Promise ();
@@ -757,20 +712,16 @@ void AskForFullDiskAccess(const Napi::CallbackInfo &info) {
757
712
Napi::Env env = info.Env ();
758
713
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New (env);
759
714
760
- if (@available (macOS 10.15 , *)) {
761
- std::string access_level = info[0 ].As <Napi::String>().Utf8Value ();
762
- std::string auth_status = InputMonitoringAuthStatus ();
715
+ std::string access_level = info[0 ].As <Napi::String>().Utf8Value ();
716
+ std::string auth_status = InputMonitoringAuthStatus ();
763
717
764
- if (auth_status == kNotDetermined ) {
765
- IOHIDRequestAccess (GetInputMonitoringAccessType (access_level));
766
- deferred.Resolve (Napi::String::New (env, kDenied ));
767
- } else {
768
- if (auth_status == kDenied )
769
- OpenPrefPane (" Privacy_ListenEvent" );
770
- deferred.Resolve (Napi::String::New (env, auth_status));
771
- }
718
+ if (auth_status == kNotDetermined ) {
719
+ IOHIDRequestAccess (GetInputMonitoringAccessType (access_level));
720
+ deferred.Resolve (Napi::String::New (env, kDenied ));
772
721
} else {
773
- deferred.Resolve (Napi::String::New (env, kAuthorized ));
722
+ if (auth_status == kDenied )
723
+ OpenPrefPane (" Privacy_ListenEvent" );
724
+ deferred.Resolve (Napi::String::New (env, auth_status));
774
725
}
775
726
776
727
return deferred.Promise ();
@@ -822,7 +773,7 @@ void AskForScreenCaptureAccess(const Napi::CallbackInfo &info) {
822
773
if (should_force_prefs && !HasOpenSystemPreferencesDialog ()) {
823
774
OpenPrefPane (" Privacy_ScreenCapture" );
824
775
}
825
- } else if (@ available (macOS 10.15 , *)) {
776
+ } else {
826
777
// Tries to create a capture stream. This is necessary to add the app back
827
778
// to the list in sysprefs if the user previously denied.
828
779
// https://stackoverflow.com/questions/56597221/detecting-screen-recording-settings-on-macos-catalina
@@ -843,20 +794,18 @@ void AskForScreenCaptureAccess(const Napi::CallbackInfo &info) {
843
794
844
795
// Request Location access.
845
796
void AskForLocationAccess (const Napi::CallbackInfo &info) {
846
- if (@available (macOS 10.15 , *)) {
847
- std::string auth_status = LocationAuthStatus ();
797
+ std::string auth_status = LocationAuthStatus ();
848
798
849
- if (auth_status == kNotDetermined ) {
850
- CLLocationManager *location_manager = [[CLLocationManager alloc ] init ];
851
- const std::string access_level = info[0 ].As <Napi::String>().Utf8Value ();
852
- if (access_level == " always" ) {
853
- [location_manager requestAlwaysAuthorization ];
854
- } else if (access_level == " when-in-use" ) {
855
- [location_manager requestWhenInUseAuthorization ];
856
- }
857
- } else if (auth_status == kDenied ) {
858
- OpenPrefPane (" Privacy_Location" );
799
+ if (auth_status == kNotDetermined ) {
800
+ CLLocationManager *location_manager = [[CLLocationManager alloc ] init ];
801
+ const std::string access_level = info[0 ].As <Napi::String>().Utf8Value ();
802
+ if (access_level == " always" ) {
803
+ [location_manager requestAlwaysAuthorization ];
804
+ } else if (access_level == " when-in-use" ) {
805
+ [location_manager requestWhenInUseAuthorization ];
859
806
}
807
+ } else if (auth_status == kDenied ) {
808
+ OpenPrefPane (" Privacy_Location" );
860
809
}
861
810
}
862
811
0 commit comments