diff --git a/lib/chrome-api-promise.js b/lib/chrome-api-promise.js index 564baa8..8cebd6d 100644 --- a/lib/chrome-api-promise.js +++ b/lib/chrome-api-promise.js @@ -34,7 +34,7 @@ function ChromePromiseApi() { if (mfest !== undefined) resolve(mfest) else - reject("Uknown error while fetching manifest") + reject("Unknown error while fetching manifest") }) } diff --git a/services/dropboxFileManager.js b/services/dropboxFileManager.js index 9af3cb1..2b6813f 100644 --- a/services/dropboxFileManager.js +++ b/services/dropboxFileManager.js @@ -1,14 +1,14 @@ "use strict"; -const Base64 = require('base64-arraybuffer') -const axios = require('axios') -import { - ChromePromiseApi -} from '$lib/chrome-api-promise.js' + +import { random } from 'case'; +import { ChromePromiseApi } from '$lib/chrome-api-promise'; import { OauthManager } from '$services/oauthManager.js' -const chromePromise = ChromePromiseApi() + +const Base64 = require('base64-arraybuffer') +const axios = require('axios') function DropboxFileManager(settings) { var accessTokenType = 'dropbox'; @@ -19,8 +19,8 @@ function DropboxFileManager(settings) { var oauth = { accessTokenType: accessTokenType, - origins: ['https://*.dropbox.com/'], - authUrl: 'https://www.dropbox.com/oauth2/authorize?response_type=token&force_reapprove=false', + origins: ['https://dropbox.com/oauth2/'], + authUrl: 'https://dropbox.com/oauth2/authorize?response_type=token&reject_cors_preflight=true', supportedFeatures: ['incognito', 'listDatabases'], title: 'Dropbox', icon: 'icon-dropbox', @@ -88,8 +88,8 @@ function DropboxFileManager(settings) { return Promise.resolve() } - oauth.handleAuthRedirectURI = function (redirect_url, randomState, resolve, reject) { - + oauth.handleAuthRedirectURI = function (redirect_url, randomState) { + console.info("OWL INFO - Redirect url:", redirect_url) var tokenMatches = /access_token=([^&]+)/.exec(redirect_url); var stateMatches = /state=([^&]+)/.exec(redirect_url); var uidMatches = /uid=(\d+)/.exec(redirect_url); @@ -101,16 +101,14 @@ function DropboxFileManager(settings) { if (checkState === randomState) { state.loggedIn = true; settings.getSetAccessToken(accessTokenType, access_token).then(function () { - resolve(access_token); + return access_token; }); } else { //some sort of error or parsing failure - reject(); console.error("OWL ERROR - " + redirect_url, " - state was found invalid"); } } else { //some sort of error - reject(); console.error("OWL ERROR - " + redirect_url, " - something was found invalid"); } } diff --git a/services/keepassService.js b/services/keepassService.js index d0ac675..3cb1f10 100644 --- a/services/keepassService.js +++ b/services/keepassService.js @@ -67,7 +67,7 @@ function KeepassService(keepassHeader, settings, passwordFileStoreRegistry, keep return processReferences(entries, majorVersion); }); } else { // KDB - we don't support this anymore - throw "Unsupported Database Version"; + throw "Unsupported Database Version - Owl does not support .kdb formats! Please update to .kdbx instead."; } }).then(function (entries) { return { diff --git a/services/oauthManager.js b/services/oauthManager.js index bdd6e6c..098aa58 100644 --- a/services/oauthManager.js +++ b/services/oauthManager.js @@ -176,20 +176,16 @@ function OauthManager(settings, oauth) { function auth(interactive) { interactive = !!interactive; - console.info("OWL INFO - Authenticating for:", oauth.accessTokenType, interactive) let authfunction = interactive => { return new Promise(function (resolve, reject) { chromePromise.runtime.getManifest().then(manifest => { - console.info("Owl auth flow is interactive", manifest, true) - console.info("Owl is using redirect url: ", chrome.identity.getRedirectURL(oauth.accessTokenType)); //random state, protects against CSRF var randomState = Base64.encode(window.crypto.getRandomValues(new Uint8Array(16))); var authUrl = oauth.authUrl + '&client_id=' + manifest.static_data[oauth.accessTokenType].client_id + '&state=' + encodeURIComponent(randomState) + '&redirect_uri=' + encodeURIComponent(chrome.identity.getRedirectURL(oauth.accessTokenType)); - console.info("OWL INFO - Sending request for AUTH to:", authUrl); chromePromise.identity.launchWebAuthFlow({ 'url': authUrl, 'interactive': interactive @@ -205,7 +201,6 @@ function OauthManager(settings, oauth) { // If the oauth provider has chosen to implement its own auth function. authfunction = oauth.auth !== undefined ? oauth.auth : authfunction; - return ensureOriginPermissions().then(ensured => { return authfunction(interactive).then(token => { if (token) { diff --git a/services/settings.js b/services/settings.js index 80be0d9..c611a79 100644 --- a/services/settings.js +++ b/services/settings.js @@ -289,6 +289,10 @@ function Settings(secureCache) { return keyGetSetter('strictMatchModeEnabled', enabled, false, 'boolean') } + exports.getSetRememberPasswordEnabled = function (enabled) { + return keyGetSetter('rememberPasswordEnabled', enabled, false, 'boolean') + } + exports.getSetNotificationsEnabled = function (enabledTypes) { return keyGetSetter('notificationsEnabled', enabledTypes, ['clipboard', 'expiration'], 'object') } diff --git a/src/components/AdvancedSettings.vue b/src/components/AdvancedSettings.vue index 387699a..25937bf 100644 --- a/src/components/AdvancedSettings.vue +++ b/src/components/AdvancedSettings.vue @@ -20,6 +20,7 @@ export default { ] }, strictMatchEnabled: false, + rememberPasswordEnabled: false, notificationsEnabled: ['expiration'], jsonState: [{ k: 'databaseUsages', // key @@ -94,6 +95,9 @@ export default { }, notificationsEnabled(newval) { this.settings.getSetNotificationsEnabled(newval) + }, + rememberPasswordEnabled(newval) { + this.settings.getSetRememberPasswordEnabled(newval) } }, methods: { @@ -121,6 +125,9 @@ export default { this.settings.getSetStrictModeEnabled().then(val => { this.strictMatchEnabled = val; }) + this.settings.getSetRememberPasswordEnabled().then(val => { + this.rememberPasswordEnabled = val; + }) if (!isFirefox()) { chrome.permissions.contains(this.allOriginPerms, granted => { this.allOriginPermission = !!granted; @@ -233,6 +240,25 @@ export default { +
+

Enable Remember Password

+

Currently, Owl cannot update your database entries when auto-unlocking is enabled. + To enable auto-updating, the Remember Password functionality was hidden. You can re-enable this functionality here, but please keep in mind that you will have to lock and unlock + your database to refresh entries. +

+
+
+
+
+ +
+
+
+

Stored Data

The following objects represent the current data cached in local storage. This data is only available to Owl, and is never sent over any network connection.

diff --git a/src/components/EntryListItem.vue b/src/components/EntryListItem.vue index 799a205..4afbd9b 100644 --- a/src/components/EntryListItem.vue +++ b/src/components/EntryListItem.vue @@ -28,12 +28,10 @@ export default { }, autofill(e) { e.stopPropagation() - console.log("autofill") this.unlockedState.autofill(this.entry); }, copy(e) { e.stopPropagation() - console.log("copy") this.unlockedState.copyPassword(this.entry); } } diff --git a/src/components/Unlock.vue b/src/components/Unlock.vue index d64fabc..5ac4ec4 100644 --- a/src/components/Unlock.vue +++ b/src/components/Unlock.vue @@ -42,6 +42,7 @@ export default { rememberPeriodText: "", databaseFileName: "", keyFilePicker: false, + rememberPasswordEnabled: false, appVersion: chrome.runtime.getManifest().version, slider_options: [{ time: 0, @@ -178,6 +179,8 @@ export default { } if (priorityEntries.length == 0) { this.unlockedMessages.warn = "No matches found for this site." + // TODO add maybe show all passwords instead + // Security? } // Cache in memory @@ -185,7 +188,7 @@ export default { this.unlockedState.cacheSet('priorityEntries', priorityEntries) this.$forceUpdate() //save longer term (in encrypted storage) - this.secureCache.save('secureCache.entries', entries); + this.secureCache.save('secureCache.entries', entries); // ref https://github.com/CER10TY/Owl/issues/8 this.busy = false }) }, @@ -249,6 +252,10 @@ export default { } }, async mounted() { + // Add remember password + this.settings.getSetRememberPasswordEnabled().then(enabled => { + this.rememberPasswordEnabled = enabled + }) // modify unlockedState internal state await this.unlockedState.getTabDetails(); @@ -295,14 +302,13 @@ export default { this.busy = true try { let entries = await this.secureCache.get('secureCache.entries'); - if (entries !== undefined && entries.length > 0) { + if (entries !== undefined && entries.length > 0 && this.rememberPeriod > 0) { this.showResults(entries) } else { try_autounlock() } } catch (err) { - console.error("OWL ERROR - " + err); - //this is fine - it just means the cache expired. Clear the cache to be sure. + //this is fine - it just means the cache expired. Clear the cache to be sure. this.secureCache.clear('secureCache.entries') try_autounlock() @@ -373,8 +379,8 @@ export default {
- -
+ +
diff --git a/src/components/WebdavProvider.vue b/src/components/WebdavProvider.vue index 1307b74..fcf8259 100644 --- a/src/components/WebdavProvider.vue +++ b/src/components/WebdavProvider.vue @@ -40,19 +40,29 @@ export default { }).then(() => { this.providerManager.addServer(this.webdav.url, this.webdav.username, this.webdav.password).then(serverInfo => { // do somethings + this.messages.error = "" return this.updateServerList().then(() => { this.scan(serverInfo.serverId) }) }).catch(err => { + console.error(err.toString()) // Very specific error msg, but makes it more human readable later - ref https://github.com/CER10TY/Owl/issues/11 if (err.toString() === "TypeError: serverListItem is undefined") { - this.messages.error = "Error: Server already defined" - } else { - this.messages.error = err.toString() + this.messages.error = "Error: Server already defined!" + } + // Discard other error messages from front end for now - many coming through that don't affect day to day. + else { + console.error("Owl: Error - ", err.toString()) } }) }).catch(err => { - this.messages.error = err.toString() + if (err.toString() === "TypeError: Cannot set property 'scanBusy' of undefined") { + // Do nothing, cause it's a garbage error + } else if (err.toString() === "Error: Invalid value for origin pattern : Missing scheme separator.") { + this.messages.error = "Error: Server address is undefined!" + } else { + this.messages.error = err.toString() + } }) }, setBusy(serverId, busy) {