diff --git a/manifest-chrome.json b/manifest-chrome.json index 1437764a2..36c166329 100644 --- a/manifest-chrome.json +++ b/manifest-chrome.json @@ -18,6 +18,9 @@ "default_title": "__MSG_extShortName__", "default_popup": "view/popup.html" }, + "storage": { + "managed_schema": "schema.json" + }, "oauth2": { "client_id": "292457304165-u8ve4j79gag5o231n5u2pdtdrbfdo1hh.apps.googleusercontent.com", "scopes": [ diff --git a/schema-chrome.json b/schema-chrome.json new file mode 100644 index 000000000..f852f93ae --- /dev/null +++ b/schema-chrome.json @@ -0,0 +1,29 @@ +{ + "type": "object", + + "properties": { + "disableInstallHelp": { + "title": "Disable opening help page on install", + "description": "If set to true then help page will not be opened on install.", + "type": "boolean" + }, + + "disableBackup": { + "title": "Disable 3rd party backup", + "description": "If set to true then 3rd party backup options will be hidden. If 3rd party backup is already configured for a user this will not stop it.", + "type": "boolean" + }, + + "storageArea": { + "title": "Storage area", + "description": "Set to 'sync' or 'local'. If set will force user to use specified storage area. This setting will not check if a user is currently using another storage space and may hide data.", + "type": "string" + }, + + "feedbackURL": { + "title": "Feedback URL", + "description": "Change the URL the feedback button opens.", + "type": "string" + } + } +} diff --git a/scripts/build.sh b/scripts/build.sh index 215908866..6ae95f287 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -58,6 +58,9 @@ if [[ $PLATFORM = "edge" ]]; then else cp -r build css images js _locales LICENSE view $PLATFORM cp manifest-$PLATFORM.json $PLATFORM/manifest.json + if [[ $PLATFORM = "chrome" ]]; then + cp schema-chrome.json $PLATFORM/schema.json + fi fi echo -e "\033[0;32mDone!\033[0m" diff --git a/src/background.ts b/src/background.ts index 60e8c990b..53a50aa61 100644 --- a/src/background.ts +++ b/src/background.ts @@ -265,9 +265,11 @@ function getBackupToken(service: string) { } // Show issue page after first install -chrome.runtime.onInstalled.addListener((details) => { +chrome.runtime.onInstalled.addListener(async (details) => { if (details.reason !== 'install') { return; + } else if (await ManagedStorage.get('disableInstallHelp')) { + return; } let url: string|null = null; diff --git a/src/models/storage.ts b/src/models/storage.ts index f5e46ec61..a928d56d1 100644 --- a/src/models/storage.ts +++ b/src/models/storage.ts @@ -4,8 +4,18 @@ /// class BrowserStorage { - private static getStorageLocation() { - if (localStorage.storageLocation !== 'sync' && + private static async getStorageLocation() { + const managedLocation = await ManagedStorage.get('storageArea'); + if (managedLocation === 'sync' || managedLocation === 'local') { + return new Promise((resolve) => { + if (localStorage.storageLocation !== managedLocation) { + localStorage.storageLocation = managedLocation; + } + resolve(managedLocation); + return; + }); + } else if ( + localStorage.storageLocation !== 'sync' && localStorage.storageLocation !== 'local') { return new Promise((resolve, reject) => { let amountSync: number; @@ -144,7 +154,7 @@ class EntryStorage { } } - static async hasEncryptedEntry() { + static hasEncryptedEntry() { return new Promise( (resolve: (value: boolean) => void, reject: (reason: Error) => void) => { @@ -163,7 +173,7 @@ class EntryStorage { }); } - static async getExport(encryption: Encryption, encrypted?: boolean) { + static getExport(encryption: Encryption, encrypted?: boolean) { return new Promise( (resolve: (value: {[hash: string]: OTPStorage}) => void, reject: (reason: Error) => void) => { @@ -201,8 +211,7 @@ class EntryStorage { }); } - static async import( - encryption: Encryption, data: {[hash: string]: OTPStorage}) { + static import(encryption: Encryption, data: {[hash: string]: OTPStorage}) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { try { @@ -285,7 +294,7 @@ class EntryStorage { }); } - static async add(encryption: Encryption, entry: OTPEntry) { + static add(encryption: Encryption, entry: OTPEntry) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { try { @@ -306,7 +315,7 @@ class EntryStorage { }); } - static async update(encryption: Encryption, entry: OTPEntry) { + static update(encryption: Encryption, entry: OTPEntry) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { try { @@ -327,7 +336,7 @@ class EntryStorage { }); } - static async set(encryption: Encryption, entries: OTPEntry[]) { + static set(encryption: Encryption, entries: OTPEntry[]) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { try { @@ -347,7 +356,7 @@ class EntryStorage { }); } - static async get(encryption: Encryption) { + static get(encryption: Encryption) { return new Promise( (resolve: (value: OTPEntry[]) => void, reject: (reason: Error) => void) => { @@ -491,14 +500,14 @@ class EntryStorage { }); } - static async remove(hash: string) { + static remove(hash: string) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { return BrowserStorage.remove(hash, resolve); }); } - static async delete(entry: OTPEntry) { + static delete(entry: OTPEntry) { return new Promise( (resolve: () => void, reject: (reason: Error) => void) => { try { @@ -519,3 +528,21 @@ class EntryStorage { }); } } + +class ManagedStorage { + static get(key: string) { + return new Promise((resolve: (result: boolean|string) => void) => { + chrome.storage.managed.get((data) => { + if (chrome.runtime.lastError) { + resolve(false); + } + if (data) { + if (data[key]) { + resolve(data[key]); + } + } + resolve(false); + }); + }); + } +} diff --git a/src/ui/menu.ts b/src/ui/menu.ts index d1a40ca08..46aa47afb 100644 --- a/src/ui/menu.ts +++ b/src/ui/menu.ts @@ -53,7 +53,7 @@ function resize(zoom: number) { } } -function openHelp() { +async function openHelp() { let url = 'https://github.com/Authenticator-Extension/Authenticator/wiki/Chrome-Issues'; @@ -65,9 +65,25 @@ function openHelp() { 'https://github.com/Authenticator-Extension/Authenticator/wiki/Edge-Issues'; } - window.open(url, '_blank'); + const feedbackURL = await ManagedStorage.get('feedbackURL'); + if (typeof feedbackURL === 'string' && feedbackURL) { + url = feedbackURL; + } + + chrome.tabs.create({url}); } +let backupDisabled: boolean|string; +let storageArea: boolean|string; + +ManagedStorage.get('disableBackup').then((value) => { + backupDisabled = value; +}); + +ManagedStorage.get('storageArea').then((value) => { + storageArea = value; +}); + async function menu(_ui: UI) { const version = getVersion(); const zoom = Number(localStorage.zoom) || 100; @@ -81,7 +97,9 @@ async function menu(_ui: UI) { zoom, useAutofill, useHighContrast, - newStorageLocation: localStorage.storageLocation + newStorageLocation: localStorage.storageLocation, + backupDisabled, + storageArea }, methods: { openLink: (url: string) => { diff --git a/view/popup.html b/view/popup.html index 5798e0af7..8fb18a20f 100644 --- a/view/popup.html +++ b/view/popup.html @@ -203,15 +203,15 @@
{{ i18n.storage_location_info }}
- -
{{ i18n.storage_sync_info }}
+
{{ i18n.storage_sync_info }}

-
Google Drive
-
Dropbox
+
Google Drive
+
Dropbox