Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow installation on all platform #75

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ If you're using macOS 12.3 or newer, you'll need to ensure you have Python insta

## API

If you use this API on other platforms than macOS, it will return `undefined` in any case.

### `permissions.getAuthStatus(type)`

* `type` String - The type of system component to which you are requesting access. Can be one of `accessibility`, `bluetooth`, `calendar`, `camera`, `contacts`, `full-disk-access`, `input-monitoring`, `location`, `microphone`,`photos`, `reminders`, `screen`, or `speech-recognition`.
Expand Down
134 changes: 114 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
const permissions = require('bindings')('permissions.node')
const isMac = process.platform === 'darwin'

function getPermissionsHandler() {
const permissions = require('bindings')('permissions.node')

return permissions
}

function getAuthStatus(type) {
if (!isMac) {
return
}

const validTypes = [
'accessibility',
'bluetooth',
Expand All @@ -23,64 +33,148 @@ function getAuthStatus(type) {
throw new TypeError(`${type} is not a valid type`)
}

return permissions.getAuthStatus.call(this, type)
return getPermissionsHandler().getAuthStatus.call(this, type)
}

function askForAccessibilityAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForAccessibilityAccess.call(this)
}

function askForFoldersAccess(folder) {
if (!isMac) {
return
}

const validFolders = ['desktop', 'documents', 'downloads']

if (!validFolders.includes(folder)) {
throw new TypeError(`${folder} is not a valid protected folder`)
}

return permissions.askForFoldersAccess.call(this, folder)
return getPermissionsHandler().askForFoldersAccess.call(this, folder)
}

function askForCalendarAccess(accessLevel = 'write-only') {
if (!isMac) {
return
}

if (!['write-only', 'full'].includes(accessLevel)) {
throw new TypeError(`${accessLevel} must be one of either 'write-only' or 'full'`)
}

return permissions.askForCalendarAccess.call(this, accessLevel)
return getPermissionsHandler().askForCalendarAccess.call(this, accessLevel)
}

function askForCameraAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForCameraAccess.call(this)
}

function askForScreenCaptureAccess(openPreferences = false) {
if (!isMac) {
return
}

if (typeof openPreferences !== 'boolean') {
throw new TypeError('openPreferences must be a boolean')
}

return permissions.askForScreenCaptureAccess.call(this, openPreferences)
return getPermissionsHandler().askForScreenCaptureAccess.call(this, openPreferences)
}

function askForPhotosAccess(accessLevel = 'add-only') {
if (!isMac) {
return
}

if (!['add-only', 'read-write'].includes(accessLevel)) {
throw new TypeError(`${accessLevel} must be one of either 'add-only' or 'read-write'`)
}

return permissions.askForPhotosAccess.call(this, accessLevel)
return getPermissionsHandler().askForPhotosAccess.call(this, accessLevel)
}

function askForInputMonitoringAccess(accessLevel = 'listen') {
if (!isMac) {
return
}

if (!['listen', 'post'].includes(accessLevel)) {
throw new TypeError(`${accessLevel} must be one of either 'listen' or 'post'`)
}

return permissions.askForInputMonitoringAccess.call(this, accessLevel)
return getPermissionsHandler().askForInputMonitoringAccess.call(this, accessLevel)
}

function askForContactsAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForContactsAccess.call(this)
}

function askForFullDiskAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForFullDiskAccess.call(this)
}

function askForRemindersAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForRemindersAccess.call(this)
}

function askForMicrophoneAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForMicrophoneAccess.call(this)
}

function askForMusicLibraryAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForMusicLibraryAccess.call(this)
}

function askForSpeechRecognitionAccess() {
if (!isMac) {
return
}

return getPermissionsHandler().askForSpeechRecognitionAccess.call(this)
}

module.exports = {
askForAccessibilityAccess: permissions.askForAccessibilityAccess,
askForAccessibilityAccess: askForAccessibilityAccess,
askForCalendarAccess: askForCalendarAccess,
askForCameraAccess: permissions.askForCameraAccess,
askForContactsAccess: permissions.askForContactsAccess,
askForFoldersAccess,
askForFullDiskAccess: permissions.askForFullDiskAccess,
askForInputMonitoringAccess,
askForRemindersAccess: permissions.askForRemindersAccess,
askForMicrophoneAccess: permissions.askForMicrophoneAccess,
askForMusicLibraryAccess: permissions.askForMusicLibraryAccess,
askForPhotosAccess,
askForSpeechRecognitionAccess: permissions.askForSpeechRecognitionAccess,
askForScreenCaptureAccess,
getAuthStatus,
askForCameraAccess: askForCameraAccess,
askForContactsAccess: askForContactsAccess,
askForFoldersAccess: askForFoldersAccess,
askForFullDiskAccess: askForFullDiskAccess,
askForInputMonitoringAccess: askForInputMonitoringAccess,
askForRemindersAccess: askForRemindersAccess,
askForMicrophoneAccess: askForMicrophoneAccess,
askForMusicLibraryAccess: askForMusicLibraryAccess,
askForPhotosAccess: askForPhotosAccess,
askForSpeechRecognitionAccess: askForSpeechRecognitionAccess,
askForScreenCaptureAccess: askForScreenCaptureAccess,
getAuthStatus: getAuthStatus,
Copy link

@mmaietta mmaietta Feb 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I think this could be refactored for a much smaller diff:

const permissions = process.platform === 'darwin' ? require('bindings')('permissions.node') : undefined

function askForAccessibilityAccess() {
  return permissions?.askForAccessibilityAccess.call(this)
}

function askForCalendarAccess(accessLevel = 'write-only') {
  if (!['write-only', 'full'].includes(accessLevel)) {
    throw new TypeError(`${accessLevel} must be one of either 'write-only' or 'full'`)
  }
  return permissions?.askForCalendarAccess.call(this, accessLevel)
}

module.exports = {
  askForAccessibilityAccess,
  askForCalendarAccess,
  askForMusicLibraryAccess: () => permissions ? permissions.askForMusicLibraryAccess.call(this) : undefined
  // ...
}

}
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,5 @@
"*.mm": [
"clang-format -i"
]
},
"os": [
"darwin"
]
}
}