diff options
Diffstat (limited to 'ext/bg/js/permissions-util.js')
-rw-r--r-- | ext/bg/js/permissions-util.js | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/ext/bg/js/permissions-util.js b/ext/bg/js/permissions-util.js new file mode 100644 index 00000000..bd3a18ce --- /dev/null +++ b/ext/bg/js/permissions-util.js @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2021 Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +class PermissionsUtil { + constructor() { + this._ankiFieldMarkersRequiringClipboardPermission = new Set([ + 'clipboard-image', + 'clipboard-text' + ]); + this._ankiMarkerPattern = /\{([\w-]+)\}/g; + } + + hasPermissions(permissions) { + return new Promise((resolve, reject) => chrome.permissions.contains(permissions, (result) => { + const e = chrome.runtime.lastError; + if (e) { + reject(new Error(e.message)); + } else { + resolve(result); + } + })); + } + + setPermissionsGranted(permissions, shouldHave) { + return ( + shouldHave ? + new Promise((resolve, reject) => chrome.permissions.request(permissions, (result) => { + const e = chrome.runtime.lastError; + if (e) { + reject(new Error(e.message)); + } else { + resolve(result); + } + })) : + new Promise((resolve, reject) => chrome.permissions.remove(permissions, (result) => { + const e = chrome.runtime.lastError; + if (e) { + reject(new Error(e.message)); + } else { + resolve(!result); + } + })) + ); + } + + getAllPermissions() { + return new Promise((resolve, reject) => chrome.permissions.getAll((result) => { + const e = chrome.runtime.lastError; + if (e) { + reject(new Error(e.message)); + } else { + resolve(result); + } + })); + } + + getRequiredPermissionsForAnkiFieldValue(fieldValue) { + const markers = this._getAnkiFieldMarkers(fieldValue); + const markerPermissions = this._ankiFieldMarkersRequiringClipboardPermission; + for (const marker of markers) { + if (markerPermissions.has(marker)) { + return ['clipboardRead']; + } + } + return []; + } + + hasRequiredPermissionsForOptions(permissions, options) { + const permissionsSet = new Set(permissions.permissions); + + if (!permissionsSet.has('nativeMessaging')) { + if (options.parsing.enableMecabParser) { + return false; + } + } + + if (!permissionsSet.has('clipboardRead')) { + if (options.clipboard.enableBackgroundMonitor || options.clipboard.enableSearchPageMonitor) { + return false; + } + const fieldMarkersRequiringClipboardPermission = this._ankiFieldMarkersRequiringClipboardPermission; + const fieldsList = [ + options.anki.terms.fields, + options.anki.kanji.fields + ]; + for (const fields of fieldsList) { + for (const fieldValue of Object.values(fields)) { + const markers = this._getAnkiFieldMarkers(fieldValue); + for (const marker of markers) { + if (fieldMarkersRequiringClipboardPermission.has(marker)) { + return false; + } + } + } + } + } + + return true; + } + + // Private + + _getAnkiFieldMarkers(fieldValue) { + const pattern = this._ankiMarkerPattern; + const markers = []; + let match; + while ((match = pattern.exec(fieldValue)) !== null) { + markers.push(match[1]); + } + return markers; + } +} |