From a360ee1308f559d63ade1c7d0bc9929aa8e0f391 Mon Sep 17 00:00:00 2001 From: antelle Date: Sun, 3 Dec 2017 09:02:27 +0100 Subject: [PATCH 01/14] fixed color flash on startup --- desktop/app.js | 3 ++- release-notes.md | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/desktop/app.js b/desktop/app.js index bb75f600..517ede9c 100644 --- a/desktop/app.js +++ b/desktop/app.js @@ -136,6 +136,7 @@ function createMainWindow() { width: 1000, height: 700, minWidth: 700, minHeight: 400, icon: path.join(__dirname, 'icon.png'), titleBarStyle: appSettings ? appSettings.titlebarStyle : undefined, + backgroundColor: '#282C34', webPreferences: { backgroundThrottling: false } @@ -145,7 +146,7 @@ function createMainWindow() { if (showDevToolsOnStart) { mainWindow.openDevTools(); } - mainWindow.webContents.on('dom-ready', () => { + mainWindow.once('ready-to-show', () => { setTimeout(() => { mainWindow.show(); ready = true; diff --git a/release-notes.md b/release-notes.md index d87ebaf7..c481afcb 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,5 +1,8 @@ Release notes ------------- +##### v1.7.0 (WIP) +`-` fixed color flash on startup + ##### v1.6.1 (2017-12-03) `-` fixed white screen on startup `+` `--devtools` command line argument From b6d507d5bcdfe630dee6f00883328d7ea205b7e9 Mon Sep 17 00:00:00 2001 From: antelle Date: Sun, 3 Dec 2017 09:04:24 +0100 Subject: [PATCH 02/14] update message wording --- app/scripts/locales/base.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/locales/base.json b/app/scripts/locales/base.json index 2652ca24..eb0afe3f 100644 --- a/app/scripts/locales/base.json +++ b/app/scripts/locales/base.json @@ -302,7 +302,7 @@ "setGenNewVersion": "New app version was released and downloaded", "setGenReleaseNotes": "View release notes", "setGenReloadToUpdate": "Reload to update", - "setGenUpdateManual": "A new version has been released. It will check for updates and install them automatically, but auto-upgrading from your version is impossible.", + "setGenUpdateManual": "A new version has been released. It will check for updates and install them automatically, but auto-upgrading from your version is not possible.", "setGenDownloadUpdate": "Download update", "setGenUpdateAuto": "Download and install automatically", "setGenUpdateCheck": "Check but don't install", From 40c3b0b5bdf1e61c0b5be4726e66c6d38c6f6a14 Mon Sep 17 00:00:00 2001 From: antelle Date: Mon, 4 Dec 2017 19:30:55 +0100 Subject: [PATCH 03/14] fixed google drive files listing --- app/scripts/views/storage-file-list-view.js | 9 ++++----- app/templates/storage-file-list.hbs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/scripts/views/storage-file-list-view.js b/app/scripts/views/storage-file-list-view.js index c43cba94..cae8187c 100644 --- a/app/scripts/views/storage-file-list-view.js +++ b/app/scripts/views/storage-file-list-view.js @@ -19,15 +19,14 @@ const StorageFileListView = Backbone.View.extend({ this.allStorageFiles[file.path] = file; return { path: file.path, - name: UrlUtil.getDataFileName(file.name), + name: file.name.replace(/\.kdbx$/i, ''), kdbx: UrlUtil.isKdbx(file.name), dir: file.dir }; }); - let hasHiddenFiles = this.showHiddenFiles; + const visibleFiles = files.filter(f => !f.dir && f.kdbx); + const canShowHiddenFiles = visibleFiles.length && files.length > visibleFiles.length; if (!this.showHiddenFiles) { - const visibleFiles = files.filter(f => !f.dir && f.kdbx); - hasHiddenFiles = files.length > visibleFiles.length; if (visibleFiles.length > 0) { files = visibleFiles; } else { @@ -39,7 +38,7 @@ const StorageFileListView = Backbone.View.extend({ files, density, showHiddenFiles: this.showHiddenFiles, - hasHiddenFiles: hasHiddenFiles + canShowHiddenFiles: canShowHiddenFiles }); return this; }, diff --git a/app/templates/storage-file-list.hbs b/app/templates/storage-file-list.hbs index d722ebeb..71375dab 100644 --- a/app/templates/storage-file-list.hbs +++ b/app/templates/storage-file-list.hbs @@ -23,7 +23,7 @@ - {{#if hasHiddenFiles}} + {{#if canShowHiddenFiles}}
From ebccdcb3f7479447aae9d3fba9c5ff0253c4c61c Mon Sep 17 00:00:00 2001 From: antelle Date: Tue, 5 Dec 2017 19:13:44 +0100 Subject: [PATCH 04/14] fix #788: added the icon to linux zip archives --- Gruntfile.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 9d156ccf..7e526bea 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -435,11 +435,13 @@ module.exports = function(grunt) { }, 'linux-x64': { options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.x64.zip` }, - files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true }] + files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true }, + { cwd: 'graphics', src: '128x128.png', nonull: true, expand: true }] }, 'linux-ia32': { options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.ia32.zip` }, - files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true }] + files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true }, + { cwd: 'graphics', src: '128x128.png', nonull: true, expand: true }] } }, appdmg: { From 0941a2666c27f56b8ddcb3e830cb4db32b0f3bf1 Mon Sep 17 00:00:00 2001 From: antelle Date: Thu, 7 Dec 2017 18:46:46 +0100 Subject: [PATCH 05/14] fixed error on open --- app/scripts/models/app-model.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/scripts/models/app-model.js b/app/scripts/models/app-model.js index d68a618d..ae01601d 100644 --- a/app/scripts/models/app-model.js +++ b/app/scripts/models/app-model.js @@ -500,6 +500,8 @@ const AppModel = Backbone.Model.extend({ needLoadKeyFile = true; } } + } else if (params.keyFilePath && !params.keyFileData && !fileInfo) { + needLoadKeyFile = true; } const file = new FileModel({ id: fileInfo ? fileInfo.id : IdGenerator.uuid(), From 869b6443e817a0ec615a217d7d87566738fd5006 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 12:22:33 +0100 Subject: [PATCH 06/14] fixed storage providers authentication in desktop apps --- app/scripts/app.js | 2 ++ app/scripts/comp/cookie-manager.js | 45 +++++++++++++++++++++++++++ app/scripts/comp/launcher-electron.js | 11 +++++++ app/scripts/storage/storage-base.js | 2 ++ 4 files changed, 60 insertions(+) create mode 100644 app/scripts/comp/cookie-manager.js diff --git a/app/scripts/app.js b/app/scripts/app.js index 4d75bb8d..ec5b060a 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -9,6 +9,7 @@ const IdleTracker = require('./comp/idle-tracker'); const PopupNotifier = require('./comp/popup-notifier'); const SingleInstanceChecker = require('./comp/single-instance-checker'); const AppRightsChecker = require('./comp/app-rights-checker'); +const CookieManager = require('./comp/cookie-manager'); const Alerts = require('./comp/alerts'); const Updater = require('./comp/updater'); const AuthReceiver = require('./comp/auth-receiver'); @@ -134,6 +135,7 @@ ready(() => { Updater.init(); SingleInstanceChecker.init(); AppRightsChecker.init(); + CookieManager.init(); setTimeout(() => PluginManager.runAutoUpdate(), Timeouts.AutoUpdatePluginsAfterStart); } diff --git a/app/scripts/comp/cookie-manager.js b/app/scripts/comp/cookie-manager.js new file mode 100644 index 00000000..e983640e --- /dev/null +++ b/app/scripts/comp/cookie-manager.js @@ -0,0 +1,45 @@ +const Logger = require('../util/logger'); +const Launcher = require('./launcher'); +const RuntimeDataModel = require('../models/runtime-data-model'); + +const CookieManager = { + logger: new Logger('cookie-manager'), + cookies: undefined, + cookiesStr: undefined, + + init() { + if (Launcher) { + this.cookies = RuntimeDataModel.instance.get('cookies'); + this.cookiesStr = JSON.stringify(this.cookies); + Launcher.setCookies(this.cookies); + } + }, + + saveCookies() { + if (Launcher) { + Launcher.getCookies((err, cookies) => { + if (err) { + return this.logger.error('Error getting cookies', err); + } + if (cookies && cookies.length) { + cookies = cookies.filter(cookie => !cookie.session).map(cookie => ({ + url: (cookie.secure ? 'https' : 'http') + '://' + cookie.domain + (cookie.path || ''), + name: cookie.name, + value: cookie.value, + domain: cookie.domain, + path: cookie.path, + secure: cookie.secure, + httpOnly: cookie.httpOnly, + expirationDate: cookie.expirationDate + })); + if (JSON.stringify(cookies) !== this.cookiesStr) { + this.cookies = cookies; + RuntimeDataModel.instance.set('cookies', cookies); + } + } + }); + } + } +}; + +module.exports = CookieManager; diff --git a/app/scripts/comp/launcher-electron.js b/app/scripts/comp/launcher-electron.js index 10dfe18c..6df8dcdd 100644 --- a/app/scripts/comp/launcher-electron.js +++ b/app/scripts/comp/launcher-electron.js @@ -252,6 +252,17 @@ const Launcher = { } } return ps; + }, + getCookies(callback) { + this.electron().remote.session.defaultSession.cookies.get({}, callback); + }, + setCookies(cookies) { + if (cookies && cookies.length) { + const session = this.electron().remote.session.defaultSession; + for (const cookie of cookies) { + session.cookies.set(cookie, () => {}); + } + } } }; diff --git a/app/scripts/storage/storage-base.js b/app/scripts/storage/storage-base.js index af9b96fd..924beeed 100644 --- a/app/scripts/storage/storage-base.js +++ b/app/scripts/storage/storage-base.js @@ -4,6 +4,7 @@ const AppSettingsModel = require('../models/app-settings-model'); const RuntimeDataModel = require('../models/runtime-data-model'); const Links = require('../const/links'); const FeatureDetector = require('../util/feature-detector'); +const CookieManager = require('../comp/cookie-manager'); const MaxRequestRetries = 3; @@ -175,6 +176,7 @@ _.extend(StorageBase.prototype, { this._oauthToken = token; this.runtimeData.set(this.name + 'OAuthToken', token); this.logger.debug('OAuth token received'); + CookieManager.saveCookies(); callback(); } }, From e6f78859a3df6f592531af43e1aa3c6a54eceb4f Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 12:43:46 +0100 Subject: [PATCH 07/14] use console.log instead of console.debug: debug is doomed --- app/scripts/util/logger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/util/logger.js b/app/scripts/util/logger.js index 148a56bc..d690059f 100644 --- a/app/scripts/util/logger.js +++ b/app/scripts/util/logger.js @@ -32,7 +32,7 @@ Logger.prototype.debug = function() { arguments[0] = this.getPrefix() + arguments[0]; if (this.level > Level.Debug) { Logger.saveLast('debug', arguments); - console.debug.apply(console, arguments); // eslint-disable-line no-console + console.log.apply(console, arguments); // eslint-disable-line no-console } }; From 93b60a173198c48cee6721d4018be6f233f36e41 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 12:44:58 +0100 Subject: [PATCH 08/14] use console.info instead of console.log --- app/scripts/util/logger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/util/logger.js b/app/scripts/util/logger.js index d690059f..e59d70aa 100644 --- a/app/scripts/util/logger.js +++ b/app/scripts/util/logger.js @@ -40,7 +40,7 @@ Logger.prototype.info = function() { arguments[0] = this.getPrefix() + arguments[0]; if (this.level > Level.Info) { Logger.saveLast('info', arguments); - console.log.apply(console, arguments); // eslint-disable-line no-console + console.info.apply(console, arguments); // eslint-disable-line no-console } }; From cfb1116b7e2c28c0c5cdd682610d900f0e2c43c5 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 16:30:48 +0100 Subject: [PATCH 09/14] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 63fd8bcb..948efaaa 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ To make Dropbox work in your self-hosted app, [go to this Wiki page](https://git The app can be built with grunt: `grunt` (html file will be in `dist/`). Desktop apps are built with `grunt desktop`. This works only in mac osx as it builds dmg; requires wine. -To run Electron app without building installer, install electron package (`npm install electron -g`), build the app with `grunt` and start in this way: +To run Electron app without building installer, build the app with `grunt` and start in this way: ```bash $ grunt dev $ npm run-script electron From de6c21715babde9f43f1828d94fb519da16668e1 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 22:18:45 +0100 Subject: [PATCH 10/14] release notes --- release-notes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/release-notes.md b/release-notes.md index c481afcb..bab13401 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,7 +1,9 @@ Release notes ------------- -##### v1.7.0 (WIP) -`-` fixed color flash on startup +##### v1.6.2 (2017-12-09) +`+` Google Drive shared files support +`-` fixed Google Drive authentication issues +`-` fixed a color flash on startup ##### v1.6.1 (2017-12-03) `-` fixed white screen on startup From 0e42436082cdf2b57c08772de0da95811c4853d0 Mon Sep 17 00:00:00 2001 From: antelle Date: Mon, 4 Dec 2017 19:50:36 +0100 Subject: [PATCH 11/14] fix 787: support shared files in Google Drive (cherry picked from commit e477a6a) --- app/scripts/locales/base.json | 2 ++ app/scripts/storage/storage-gdrive.js | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/scripts/locales/base.json b/app/scripts/locales/base.json index eb0afe3f..166bda44 100644 --- a/app/scripts/locales/base.json +++ b/app/scripts/locales/base.json @@ -519,6 +519,8 @@ "dropboxLinkFull": "Full Dropbox or any folder", "dropboxLinkCustom": "Own Dropbox app", + "gdriveSharedWithMe": "Shared with me", + "webdavSaveMethod": "Save method", "webdavSaveMove": "Upload a temporary file and move", "webdavSavePut": "Overwrite kdbx file with PUT", diff --git a/app/scripts/storage/storage-gdrive.js b/app/scripts/storage/storage-gdrive.js index 7f933dd1..9f74ac43 100644 --- a/app/scripts/storage/storage-gdrive.js +++ b/app/scripts/storage/storage-gdrive.js @@ -1,4 +1,5 @@ const StorageBase = require('./storage-base'); +const Locale = require('../util/locale'); const GDriveClientId = '847548101761-koqkji474gp3i2gn3k5omipbfju7pbt1.apps.googleusercontent.com'; const NewFileIdPrefix = 'NewFile:'; @@ -131,10 +132,12 @@ const StorageGDrive = StorageBase.extend({ this._oauthAuthorize((err) => { if (err) { return callback && callback(err); } this.logger.debug('List'); - const parents = dir || 'root'; + let query = dir === 'shared' ? 'sharedWithMe=true' + : dir ? `parents="${dir}"` : 'parents="root"'; + query += 'and trashed=false'; const url = this._baseUrl + '/files?fields={fields}&q={q}' .replace('{fields}', encodeURIComponent('files(id,name,mimeType,headRevisionId)')) - .replace('{q}', encodeURIComponent(`parents="${parents}" and trashed=false`)); + .replace('{q}', encodeURIComponent(query)); const ts = this.logger.ts(); this._xhr({ url: url, @@ -151,6 +154,14 @@ const StorageGDrive = StorageBase.extend({ rev: f.headRevisionId, dir: f.mimeType === 'application/vnd.google-apps.folder' })); + if (!dir) { + fileList.unshift({ + name: Locale.gdriveSharedWithMe, + path: 'shared', + rev: undefined, + dir: true + }); + } return callback && callback(null, fileList); }, error: (err) => { From eedc51f48a5b1d62a9de648a81a18ed8ebef48c0 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 22:24:50 +0100 Subject: [PATCH 12/14] fixed cookie-manager --- app/scripts/comp/cookie-manager.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/scripts/comp/cookie-manager.js b/app/scripts/comp/cookie-manager.js index e983640e..bf09704a 100644 --- a/app/scripts/comp/cookie-manager.js +++ b/app/scripts/comp/cookie-manager.js @@ -32,8 +32,10 @@ const CookieManager = { httpOnly: cookie.httpOnly, expirationDate: cookie.expirationDate })); - if (JSON.stringify(cookies) !== this.cookiesStr) { + const cookiesStr = JSON.stringify(cookies); + if (cookiesStr !== this.cookiesStr) { this.cookies = cookies; + this.cookiesStr = cookiesStr; RuntimeDataModel.instance.set('cookies', cookies); } } From 4b7f6fdf9b8d123d5e18d88f66e434a8f2552c92 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 22:25:25 +0100 Subject: [PATCH 13/14] bump version --- desktop/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index f64bb49b..f9833388 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,6 +1,6 @@ { "name": "KeeWeb", - "version": "1.6.1", + "version": "1.6.2", "description": "Free cross-platform password manager compatible with KeePass", "main": "main.js", "homepage": "https://keeweb.info", diff --git a/package.json b/package.json index 2c71e6a6..9a1bb559 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keeweb", - "version": "1.6.1", + "version": "1.6.2", "description": "Free cross-platform password manager compatible with KeePass", "main": "Gruntfile.js", "private": true, From 977cd001878446d47098e3fa5e84fe3762d83edf Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 9 Dec 2017 21:46:08 +0100 Subject: [PATCH 14/14] fix #799: gdrive auth error (cherry picked from commit 02aa303) --- app/scripts/storage/storage-base.js | 35 +++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/app/scripts/storage/storage-base.js b/app/scripts/storage/storage-base.js index 924beeed..7fc552c5 100644 --- a/app/scripts/storage/storage-base.js +++ b/app/scripts/storage/storage-base.js @@ -36,7 +36,7 @@ _.extend(StorageBase.prototype, { this.logger = new Logger('storage-' + this.name); if (this._oauthReturnMessage) { this.logger.debug('OAuth return message', this._oauthReturnMessage); - this._oauthProcessReturn(this._oauthReturnMessage, _.noop); + this._oauthProcessReturn(this._oauthReturnMessage); delete this._oauthReturnMessage; delete sessionStorage.authStorage; } @@ -159,31 +159,42 @@ _.extend(StorageBase.prototype, { if (!e.data) { return; } - Backbone.off('popup-closed', popupClosed); - window.removeEventListener('message', windowMessage); - this._oauthProcessReturn(e.data, callback); + const token = this._oauthProcessReturn(e.data); + if (token) { + Backbone.off('popup-closed', popupClosed); + window.removeEventListener('message', windowMessage); + if (token.error) { + this.logger.error('OAuth error', token.error, token.errorDescription); + callback('OAuth: ' + token.error); + } else { + callback(); + } + } else { + this.logger.debug('Skipped OAuth message', e.data); + } }; Backbone.on('popup-closed', popupClosed); window.addEventListener('message', windowMessage); }, - _oauthProcessReturn: function(message, callback) { + _oauthProcessReturn: function(message) { const token = this._oauthMsgToToken(message); - if (token.error) { - this.logger.error('OAuth error', token.error, token.errorDescription); - callback('OAuth: ' + token.error); - } else { + if (token && !token.error) { this._oauthToken = token; this.runtimeData.set(this.name + 'OAuthToken', token); this.logger.debug('OAuth token received'); CookieManager.saveCookies(); - callback(); } + return token; }, _oauthMsgToToken: function(data) { - if (data.error || !data.token_type) { - return { error: data.error || 'no token', errorDescription: data.error_description }; + if (!data.token_type) { + if (data.error) { + return {error: data.error, errorDescription: data.error_description}; + } else { + return undefined; + } } return { dt: Date.now() - 60 * 1000,