diff options
-rw-r--r-- | package-lock.json | 123 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/electron/macOSPermissions.js | 86 | ||||
-rw-r--r-- | src/index.js | 3 |
4 files changed, 97 insertions, 117 deletions
diff --git a/package-lock.json b/package-lock.json index 801d17746..913d50b4c 100644 --- a/package-lock.json +++ b/package-lock.json | |||
@@ -26512,113 +26512,6 @@ | |||
26512 | } | 26512 | } |
26513 | } | 26513 | } |
26514 | }, | 26514 | }, |
26515 | "mac-screen-capture-permissions": { | ||
26516 | "version": "1.1.0", | ||
26517 | "resolved": "https://registry.npmjs.org/mac-screen-capture-permissions/-/mac-screen-capture-permissions-1.1.0.tgz", | ||
26518 | "integrity": "sha512-jMRumlB3FScui/7yW+5FqqbuO7CQ0XOJVT5oTsb7W9eRQDhCIpJpIF0XxLVXwq2DIOp0fYsz1LFiBjnyDYULyQ==", | ||
26519 | "requires": { | ||
26520 | "electron-util": "^0.13.0", | ||
26521 | "execa": "^2.0.4", | ||
26522 | "macos-version": "^5.2.0" | ||
26523 | }, | ||
26524 | "dependencies": { | ||
26525 | "cross-spawn": { | ||
26526 | "version": "7.0.3", | ||
26527 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||
26528 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||
26529 | "requires": { | ||
26530 | "path-key": "^3.1.0", | ||
26531 | "shebang-command": "^2.0.0", | ||
26532 | "which": "^2.0.1" | ||
26533 | } | ||
26534 | }, | ||
26535 | "electron-util": { | ||
26536 | "version": "0.13.1", | ||
26537 | "resolved": "https://registry.npmjs.org/electron-util/-/electron-util-0.13.1.tgz", | ||
26538 | "integrity": "sha512-CvOuAyQPaPtnDp7SspwnT1yTb1yynw6yp4LrZCfEJ7TG/kJFiZW9RqMHlCEFWMn3QNoMkNhGVeCvWJV5NsYyuQ==", | ||
26539 | "requires": { | ||
26540 | "electron-is-dev": "^1.1.0", | ||
26541 | "new-github-issue-url": "^0.2.1" | ||
26542 | } | ||
26543 | }, | ||
26544 | "execa": { | ||
26545 | "version": "2.1.0", | ||
26546 | "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", | ||
26547 | "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", | ||
26548 | "requires": { | ||
26549 | "cross-spawn": "^7.0.0", | ||
26550 | "get-stream": "^5.0.0", | ||
26551 | "is-stream": "^2.0.0", | ||
26552 | "merge-stream": "^2.0.0", | ||
26553 | "npm-run-path": "^3.0.0", | ||
26554 | "onetime": "^5.1.0", | ||
26555 | "p-finally": "^2.0.0", | ||
26556 | "signal-exit": "^3.0.2", | ||
26557 | "strip-final-newline": "^2.0.0" | ||
26558 | } | ||
26559 | }, | ||
26560 | "get-stream": { | ||
26561 | "version": "5.2.0", | ||
26562 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", | ||
26563 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", | ||
26564 | "requires": { | ||
26565 | "pump": "^3.0.0" | ||
26566 | } | ||
26567 | }, | ||
26568 | "is-stream": { | ||
26569 | "version": "2.0.0", | ||
26570 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", | ||
26571 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" | ||
26572 | }, | ||
26573 | "npm-run-path": { | ||
26574 | "version": "3.1.0", | ||
26575 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", | ||
26576 | "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", | ||
26577 | "requires": { | ||
26578 | "path-key": "^3.0.0" | ||
26579 | } | ||
26580 | }, | ||
26581 | "onetime": { | ||
26582 | "version": "5.1.2", | ||
26583 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", | ||
26584 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", | ||
26585 | "requires": { | ||
26586 | "mimic-fn": "^2.1.0" | ||
26587 | } | ||
26588 | }, | ||
26589 | "p-finally": { | ||
26590 | "version": "2.0.1", | ||
26591 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", | ||
26592 | "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" | ||
26593 | }, | ||
26594 | "path-key": { | ||
26595 | "version": "3.1.1", | ||
26596 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||
26597 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" | ||
26598 | }, | ||
26599 | "shebang-command": { | ||
26600 | "version": "2.0.0", | ||
26601 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||
26602 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||
26603 | "requires": { | ||
26604 | "shebang-regex": "^3.0.0" | ||
26605 | } | ||
26606 | }, | ||
26607 | "shebang-regex": { | ||
26608 | "version": "3.0.0", | ||
26609 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||
26610 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" | ||
26611 | }, | ||
26612 | "which": { | ||
26613 | "version": "2.0.2", | ||
26614 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||
26615 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||
26616 | "requires": { | ||
26617 | "isexe": "^2.0.0" | ||
26618 | } | ||
26619 | } | ||
26620 | } | ||
26621 | }, | ||
26622 | "macos-release": { | 26515 | "macos-release": { |
26623 | "version": "2.4.1", | 26516 | "version": "2.4.1", |
26624 | "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz", | 26517 | "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz", |
@@ -28178,6 +28071,22 @@ | |||
28178 | } | 28071 | } |
28179 | } | 28072 | } |
28180 | }, | 28073 | }, |
28074 | "node-mac-permissions": { | ||
28075 | "version": "2.2.0", | ||
28076 | "resolved": "https://registry.npmjs.org/node-mac-permissions/-/node-mac-permissions-2.2.0.tgz", | ||
28077 | "integrity": "sha512-oLEZY46M47A/rcMacPEqo/5z6u7alXdMXhtE7xPDyMixZF35Grl9KGx3N2adE3//lEtGL6Tig98p+1gkonkwQg==", | ||
28078 | "requires": { | ||
28079 | "bindings": "^1.5.0", | ||
28080 | "node-addon-api": "^2.0.0" | ||
28081 | }, | ||
28082 | "dependencies": { | ||
28083 | "node-addon-api": { | ||
28084 | "version": "2.0.2", | ||
28085 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", | ||
28086 | "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" | ||
28087 | } | ||
28088 | } | ||
28089 | }, | ||
28181 | "node-modules-regexp": { | 28090 | "node-modules-regexp": { |
28182 | "version": "1.0.0", | 28091 | "version": "1.0.0", |
28183 | "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", | 28092 | "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", |
diff --git a/package.json b/package.json index 2acae006c..1174f9810 100644 --- a/package.json +++ b/package.json | |||
@@ -93,7 +93,6 @@ | |||
93 | "hex-to-rgba": "1.0.2", | 93 | "hex-to-rgba": "1.0.2", |
94 | "jsonwebtoken": "8.5.1", | 94 | "jsonwebtoken": "8.5.1", |
95 | "lodash": "4.17.21", | 95 | "lodash": "4.17.21", |
96 | "mac-screen-capture-permissions": "1.1.0", | ||
97 | "macos-version": "5.2.0", | 96 | "macos-version": "5.2.0", |
98 | "marked": "0.7.0", | 97 | "marked": "0.7.0", |
99 | "mdi": "^1.9.33", | 98 | "mdi": "^1.9.33", |
@@ -106,6 +105,7 @@ | |||
106 | "moment": "2.29.1", | 105 | "moment": "2.29.1", |
107 | "ms": "2.1.2", | 106 | "ms": "2.1.2", |
108 | "node-fetch": "2.6.1", | 107 | "node-fetch": "2.6.1", |
108 | "node-mac-permissions": "2.2.0", | ||
109 | "normalize-url": "5.0.0", | 109 | "normalize-url": "5.0.0", |
110 | "os-name": "4.0.0", | 110 | "os-name": "4.0.0", |
111 | "pretty-bytes": "^5.6.0", | 111 | "pretty-bytes": "^5.6.0", |
diff --git a/src/electron/macOSPermissions.js b/src/electron/macOSPermissions.js index 4ba6a7619..682a46a41 100644 --- a/src/electron/macOSPermissions.js +++ b/src/electron/macOSPermissions.js | |||
@@ -1,14 +1,84 @@ | |||
1 | import { systemPreferences } from 'electron'; | 1 | import { app, systemPreferences, dialog } from 'electron'; |
2 | import { | 2 | import fs from 'fs'; |
3 | hasScreenCapturePermission, | 3 | import macosVersion from 'macos-version'; |
4 | hasPromptedForPermission, | 4 | import path from 'path'; |
5 | } from 'mac-screen-capture-permissions'; | 5 | import { isMac } from '../environment'; |
6 | 6 | ||
7 | export default function () { | 7 | let askForScreenCaptureAccess; |
8 | if (isMac) { | ||
9 | // eslint-disable-next-line global-require | ||
10 | askForScreenCaptureAccess = require('node-mac-permissions').askForScreenCaptureAccess; | ||
11 | } | ||
12 | |||
13 | const debug = require('debug')('Franz:macOSPermissions'); | ||
14 | |||
15 | const permissionExists = macosVersion.isGreaterThanOrEqualTo('10.15'); | ||
16 | const filePath = path.join(app.getPath('userData'), '.has-app-requested-screen-capture-permissions'); | ||
17 | |||
18 | function hasPromptedForPermission() { | ||
19 | if (!permissionExists) { | ||
20 | return false; | ||
21 | } | ||
22 | |||
23 | if (filePath && fs.existsSync(filePath)) { | ||
24 | return true; | ||
25 | } | ||
26 | |||
27 | return false; | ||
28 | } | ||
29 | |||
30 | function hasScreenCapturePermission() { | ||
31 | if (!permissionExists) { | ||
32 | return true; | ||
33 | } | ||
34 | |||
35 | const screenCaptureStatus = systemPreferences.getMediaAccessStatus('screen'); | ||
36 | return screenCaptureStatus === 'granted'; | ||
37 | } | ||
38 | |||
39 | function createStatusFile() { | ||
40 | try { | ||
41 | fs.writeFileSync(filePath, ''); | ||
42 | } catch (error) { | ||
43 | if (error.code === 'ENOENT') { | ||
44 | fs.mkdirSync(path.dirname(filePath)); | ||
45 | fs.writeFileSync(filePath, ''); | ||
46 | } | ||
47 | |||
48 | throw error; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | |||
53 | export default async function (mainWindow) { | ||
54 | debug('Checking camera & microphone permissions'); | ||
8 | systemPreferences.askForMediaAccess('camera'); | 55 | systemPreferences.askForMediaAccess('camera'); |
9 | systemPreferences.askForMediaAccess('microphone'); | 56 | systemPreferences.askForMediaAccess('microphone'); |
10 | 57 | ||
11 | if (!hasPromptedForPermission()) { | 58 | if (!hasPromptedForPermission() && !hasScreenCapturePermission()) { |
12 | hasScreenCapturePermission(); | 59 | debug('Checking screen capture permissions'); |
60 | |||
61 | const { response } = await dialog.showMessageBox(mainWindow, { | ||
62 | type: 'info', | ||
63 | message: 'Enable Screen Sharing', | ||
64 | detail: 'To enable screen sharing for some services, Franz needs the permission to record your screen.', | ||
65 | buttons: [ | ||
66 | 'Allow screen sharing', | ||
67 | 'No', | ||
68 | 'Ask me later', | ||
69 | ], | ||
70 | defaultId: 0, | ||
71 | cancelId: 2, | ||
72 | }); | ||
73 | |||
74 | console.log('result', response); | ||
75 | if (response === 0) { | ||
76 | debug('Asking for access'); | ||
77 | askForScreenCaptureAccess(); | ||
78 | createStatusFile(); | ||
79 | } else if (response === 1) { | ||
80 | debug('Don\'t ask again'); | ||
81 | createStatusFile(); | ||
82 | } | ||
13 | } | 83 | } |
14 | } | 84 | } |
diff --git a/src/index.js b/src/index.js index 2586ab401..d251af958 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -10,6 +10,7 @@ import fs from 'fs-extra'; | |||
10 | import path from 'path'; | 10 | import path from 'path'; |
11 | import windowStateKeeper from 'electron-window-state'; | 11 | import windowStateKeeper from 'electron-window-state'; |
12 | import { enforceMacOSAppLocation } from 'electron-util'; | 12 | import { enforceMacOSAppLocation } from 'electron-util'; |
13 | import ms from 'ms'; | ||
13 | 14 | ||
14 | // TODO: This seems to be duplicated between here and 'config.js' | 15 | // TODO: This seems to be duplicated between here and 'config.js' |
15 | // Set app directory before loading user modules | 16 | // Set app directory before loading user modules |
@@ -328,7 +329,7 @@ const createWindow = () => { | |||
328 | }); | 329 | }); |
329 | 330 | ||
330 | if (isMac) { | 331 | if (isMac) { |
331 | askFormacOSPermissions(); | 332 | setTimeout(() => askFormacOSPermissions(mainWindow), ms('30s')); |
332 | } | 333 | } |
333 | 334 | ||
334 | mainWindow.on('show', () => { | 335 | mainWindow.on('show', () => { |