aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/permissions.md31
-rw-r--r--ext/bg/js/permissions-main.js87
-rw-r--r--ext/bg/permissions.html144
3 files changed, 262 insertions, 0 deletions
diff --git a/docs/permissions.md b/docs/permissions.md
new file mode 100644
index 00000000..8156c746
--- /dev/null
+++ b/docs/permissions.md
@@ -0,0 +1,31 @@
+# Yomichan Permissions
+
+* `<all_urls>` <br>
+ Yomichan requires access to all URLs in order to run scripts to scan text and show the definitions popup,
+ request audio for playback and download, and connect with Anki.
+
+* `storage` and `unlimitedStorage` <br>
+ Yomichan uses storage permissions in order to save extension settings and dictionary data.
+ `unlimitedStorage` is used to help prevent web browsers from unexpectedly
+ deleting dictionary data.
+
+* `webRequest` and `webRequestBlocking` <br>
+ Yomichan uses these permissions to ensure certain requests have valid and secure headers.
+ This sometimes involves removing or changing the `Origin` request header,
+ as this can be used to fingerprint browser configuration.
+
+* `nativeMessaging` <br>
+ Yomichan has the ability to communicate with an optional native messaging component in order to support
+ parsing large blocks of Japanese text using
+ [MeCab](https://en.wikipedia.org/wiki/MeCab).
+ The installation of this component is optional and is not included by default.
+
+* `clipboardWrite` <br>
+ Yomichan supports simulating the `Ctrl+C` (copy to clipboard) keyboard shortcut
+ when a definitions popup is open and focused.
+
+* `clipboardRead` (optional) <br>
+ Yomichan supports automatically opening a search window when Japanese text is copied to the clipboard
+ while the browser is running, depending on how certain settings are configured.
+ This allows Yomichan to support scanning text from external applications, provided there is a way
+ to copy text from those applications to the clipboard.
diff --git a/ext/bg/js/permissions-main.js b/ext/bg/js/permissions-main.js
new file mode 100644
index 00000000..3e46c3f2
--- /dev/null
+++ b/ext/bg/js/permissions-main.js
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 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/>.
+ */
+
+/* global
+ * api
+ */
+
+async function setupEnvironmentInfo() {
+ const {browser, platform} = await api.getEnvironmentInfo();
+ document.documentElement.dataset.browser = browser;
+ document.documentElement.dataset.os = platform.os;
+}
+
+async function isAllowedIncognitoAccess() {
+ return await new Promise((resolve) => chrome.extension.isAllowedIncognitoAccess(resolve));
+}
+
+async function isAllowedFileSchemeAccess() {
+ return await new Promise((resolve) => chrome.extension.isAllowedFileSchemeAccess(resolve));
+}
+
+async function hasPermissions(permissions) {
+ return await new Promise((resolve) => chrome.permissions.contains({permissions}, resolve));
+}
+
+async function setPermissionsGranted(permissions, shouldHave) {
+ const has = await hasPermissions(permissions);
+ if (shouldHave === has) { return has; }
+
+ return await (
+ shouldHave ?
+ new Promise((resolve) => chrome.permissions.request({permissions}, resolve)) :
+ new Promise((resolve) => chrome.permissions.remove({permissions}, (v) => resolve(!v)))
+ );
+}
+
+(async () => {
+ try {
+ document.querySelector('#content-scroll-focus').focus();
+ document.querySelector('#extension-id-example').textContent = chrome.runtime.getURL('/');
+
+ api.forwardLogsToBackend();
+ await yomichan.prepare();
+
+ setupEnvironmentInfo();
+
+ const permissionsCheckboxes = [
+ document.querySelector('#permission-checkbox-clipboard-read'),
+ document.querySelector('#permission-checkbox-allow-in-private-windows'),
+ document.querySelector('#permission-checkbox-allow-file-url-access')
+ ];
+
+ const permissions = await Promise.all([
+ hasPermissions(['clipboardRead']),
+ isAllowedIncognitoAccess(),
+ isAllowedFileSchemeAccess()
+ ]);
+
+ for (let i = 0, ii = permissions.length; i < ii; ++i) {
+ permissionsCheckboxes[i].checked = permissions[i];
+ }
+
+ permissionsCheckboxes[0].addEventListener('change', (e) => {
+ setPermissionsGranted(['clipboardRead'], e.currentTarget.checked);
+ });
+
+ await promiseTimeout(100);
+
+ document.documentElement.dataset.loaded = 'true';
+ } catch (e) {
+ yomichan.logError(e);
+ }
+})();
diff --git a/ext/bg/permissions.html b/ext/bg/permissions.html
new file mode 100644
index 00000000..a1138aee
--- /dev/null
+++ b/ext/bg/permissions.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <title>Yomichan Permissions</title>
+ <link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
+ <link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
+ <link rel="icon" type="image/png" href="/mixed/img/icon32.png" sizes="32x32">
+ <link rel="icon" type="image/png" href="/mixed/img/icon38.png" sizes="38x38">
+ <link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
+ <link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
+ <link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
+ <link rel="stylesheet" type="text/css" href="/bg/css/settings2.css">
+</head>
+<body>
+
+<!-- Main content -->
+<div class="content-outer"><div class="content">
+<div class="content-center">
+
+ <span tabindex="-1" id="content-scroll-focus"></span>
+
+ <h1>Yomichan Permissions</h1>
+
+ <h2 id="permissions"></h2>
+ <div class="settings-group">
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>&lt;all_urls&gt;</code></div>
+ <div class="settings-item-description">
+ Yomichan requires access to all URLs in order to run scripts to scan text and show the definitions popup,
+ request audio for playback and download, and connect with Anki.
+ </div>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>storage</code> and <code>unlimitedStorage</code></div>
+ <div class="settings-item-description">
+ Yomichan uses storage permissions in order to save extension settings and dictionary data.
+ <code>unlimitedStorage</code> is used to help prevent web browsers from unexpectedly
+ deleting dictionary data.
+ </div>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>webRequest</code> and <code>webRequestBlocking</code></div>
+ <div class="settings-item-description">
+ <p>
+ Yomichan uses these permissions to ensure certain requests have valid and secure headers.
+ This sometimes involves removing or changing the <code>Origin</code> request header,
+ as this can be used to fingerprint browser configuration.
+ </p>
+ <p>
+ Example: <code>Origin: <span id="extension-id-example"></span></code>
+ </p>
+ </div>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>nativeMessaging</code></div>
+ <div class="settings-item-description">
+ Yomichan has the ability to communicate with an optional native messaging component in order to support
+ parsing large blocks of Japanese text using
+ <a href="https://en.wikipedia.org/wiki/MeCab" target="_blank" rel="noopener noreferrer">MeCab</a>.
+ The installation of this component is optional and is not included by default.
+ </div>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>clipboardWrite</code></div>
+ <div class="settings-item-description">
+ Yomichan supports simulating the <code>Ctrl+C</code> (copy to clipboard) keyboard shortcut
+ when a definitions popup is open and focused.
+ </div>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label"><code>clipboardRead</code> <span class="light">(optional)</span></div>
+ <div class="settings-item-description">
+ Yomichan supports automatically opening a search window when Japanese text is copied to the clipboard
+ while the browser is running, depending on how certain settings are configured.
+ This allows Yomichan to support scanning text from external applications, provided there is a way
+ to copy text from those applications to the clipboard.
+ </div>
+ </div>
+ <div class="settings-item-right">
+ <label class="toggle"><input type="checkbox" id="permission-checkbox-clipboard-read"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label">Allow in private windows <span class="light">(optional)</span></div>
+ <div class="settings-item-description">
+ <p>
+ When enabled, Yomichan is able to scan text and show definitions in private/incognito web browser windows.
+ </p>
+ <p>
+ This option can be configured from the web browser's extension settings pages.
+ </p>
+ </div>
+ </div>
+ <div class="settings-item-right">
+ <label class="toggle"><input type="checkbox" id="permission-checkbox-allow-in-private-windows" disabled><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
+ </div>
+ </div></div>
+ <div class="settings-item"><div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label">Allow access to file URLs <span class="light">(optional)</span></div>
+ <div class="settings-item-description">
+ <p>
+ When enabled, Yomichan is able to scan text and show definitions on local HTML files located using the <code>file://*</code> scheme.
+ </p>
+ <p data-show-for-browser="chrome edge">
+ This option can be configured from the web browser's extension settings pages.
+ </p>
+ </div>
+ </div>
+ <div class="settings-item-right">
+ <label class="toggle"><input type="checkbox" id="permission-checkbox-allow-file-url-access" disabled><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
+ </div>
+ </div></div>
+ </div>
+
+ <div class="footer-padding"></div>
+
+</div>
+</div></div>
+
+<!-- Scripts -->
+<script src="/mixed/js/core.js"></script>
+<script src="/mixed/js/yomichan.js"></script>
+<script src="/mixed/js/comm.js"></script>
+<script src="/mixed/js/api.js"></script>
+
+<script src="/bg/js/permissions-main.js"></script>
+
+</body>
+</html>