From cc9e369b6f17a47630754b9c1900590b13cb7db3 Mon Sep 17 00:00:00 2001 From: antelle Date: Sun, 6 Oct 2019 08:48:11 +0200 Subject: [PATCH] fix #963: keyboard shortcut to copy OTP in background --- app/scripts/comp/app/shortcuts.js | 4 +++ app/scripts/locales/base.json | 1 + app/scripts/views/details/details-view.js | 30 ++++++++++++------- .../views/settings/settings-shortcuts-view.js | 3 +- app/templates/settings/settings-shortcuts.hbs | 4 ++- desktop/app.js | 19 +++++++----- release-notes.md | 1 + 7 files changed, 41 insertions(+), 21 deletions(-) diff --git a/app/scripts/comp/app/shortcuts.js b/app/scripts/comp/app/shortcuts.js index aca9afef..50e76f6e 100644 --- a/app/scripts/comp/app/shortcuts.js +++ b/app/scripts/comp/app/shortcuts.js @@ -23,6 +23,7 @@ const globalShortcuts = { copyPassword: { mac: 'Ctrl+Alt+C', all: 'Shift+Alt+C' }, copyUser: { mac: 'Ctrl+Alt+B', all: 'Shift+Alt+B' }, copyUrl: { mac: 'Ctrl+Alt+U', all: 'Shift+Alt+U' }, + copyOtp: {}, autoType: { mac: 'Ctrl+Alt+T', all: 'Shift+Alt+T' } }; @@ -48,6 +49,9 @@ const Shortcuts = { }; }, presentShortcut(shortcutValue, formatting) { + if (!shortcutValue) { + return '-'; + } return shortcutValue .split(/\+/g) .map(part => { diff --git a/app/scripts/locales/base.json b/app/scripts/locales/base.json index 5cb7de42..36925988 100644 --- a/app/scripts/locales/base.json +++ b/app/scripts/locales/base.json @@ -518,6 +518,7 @@ "setShCopyPassGlobal": "copy password (when the app is in background)", "setShCopyUserGlobal": "copy user (when the app is in background)", "setShCopyUrlGlobal": "copy website (when the app is in background)", + "setShCopyOtpGlobal": "copy OTP (when the app is in background)", "setShAutoTypeGlobal": "auto-type (when the app is in background)", "setShLock": "lock database", "setShEdit": "Press a new key combination to set it as shortcut", diff --git a/app/scripts/views/details/details-view.js b/app/scripts/views/details/details-view.js index 284a70f3..e3c09f66 100644 --- a/app/scripts/views/details/details-view.js +++ b/app/scripts/views/details/details-view.js @@ -45,6 +45,7 @@ class DetailsView extends View { passEditView = null; userEditView = null; urlEditView = null; + otpEditView = null; fieldCopyTip = null; events = { @@ -71,6 +72,7 @@ class DetailsView extends View { this.listenTo(Events, 'copy-password', this.copyPassword); this.listenTo(Events, 'copy-user', this.copyUserName); this.listenTo(Events, 'copy-url', this.copyUrl); + this.listenTo(Events, 'copy-otp', this.copyOtp); this.listenTo(Events, 'toggle-settings', this.settingsToggled); this.listenTo(Events, 'context-menu-select', this.contextMenuSelect); this.listenTo(Events, 'set-locale', this.render); @@ -273,18 +275,18 @@ class DetailsView extends View { } }) ); + this.otpEditView = null; for (const field of Object.keys(model.fields)) { if (field === 'otp' && this.model.otpGenerator) { - this.fieldViews.push( - new FieldViewOtp({ - name: '$' + field, - title: field, - value() { - return model.otpGenerator; - }, - sequence: '{TOTP}' - }) - ); + this.otpEditView = new FieldViewOtp({ + name: '$' + field, + title: field, + value() { + return model.otpGenerator; + }, + sequence: '{TOTP}' + }); + this.fieldViews.push(this.otpEditView); } else { this.fieldViews.push( new FieldViewCustom({ @@ -594,7 +596,7 @@ class DetailsView extends View { return false; } if (!window.getSelection().toString()) { - const fieldValue = editView.value; + const fieldValue = editView.otpValue || editView.value; const fieldText = fieldValue && fieldValue.isProtected ? fieldValue.getText() : fieldValue; if (!fieldText) { @@ -629,6 +631,12 @@ class DetailsView extends View { this.copyKeyPress(this.urlEditView); } + copyOtp() { + if (this.otpEditView) { + this.copyKeyPress(this.otpEditView); + } + } + showCopyTip() { if (this.helpTipCopyShown) { return; diff --git a/app/scripts/views/settings/settings-shortcuts-view.js b/app/scripts/views/settings/settings-shortcuts-view.js index 8605bdb2..b48639bd 100644 --- a/app/scripts/views/settings/settings-shortcuts-view.js +++ b/app/scripts/views/settings/settings-shortcuts-view.js @@ -39,10 +39,11 @@ class SettingsShortcutsView extends View { autoTypeSupported: !!Launcher, globalShortcuts: Launcher ? { + autoType: Shortcuts.globalShortcutText('autoType', true), copyPassword: Shortcuts.globalShortcutText('copyPassword', true), copyUser: Shortcuts.globalShortcutText('copyUser', true), copyUrl: Shortcuts.globalShortcutText('copyUrl', true), - autoType: Shortcuts.globalShortcutText('autoType', true) + copyOtp: Shortcuts.globalShortcutText('copyOtp', true) } : undefined }); diff --git a/app/templates/settings/settings-shortcuts.hbs b/app/templates/settings/settings-shortcuts.hbs index 023b763a..655afe6a 100644 --- a/app/templates/settings/settings-shortcuts.hbs +++ b/app/templates/settings/settings-shortcuts.hbs @@ -20,6 +20,8 @@
{{{cmd}}}, {{res 'setShSet'}}
{{{cmd}}}L {{res 'setShLock'}}
{{#if globalShortcuts}} +
{{res 'setShAutoTypeGlobal'}}
{{res 'setShCopyPassGlobal'}}
{{res 'setShCopyUrlGlobal'}}
{{res 'setShAutoTypeGlobal'}}
+ data-shortcut="copyOtp">{{{globalShortcuts.copyOtp}}} {{res 'setShCopyOtpGlobal'}} {{/if}} diff --git a/desktop/app.js b/desktop/app.js index 262da65f..5ecb0bb7 100644 --- a/desktop/app.js +++ b/desktop/app.js @@ -67,7 +67,7 @@ app.on('ready', () => { setAppOptions(); setSystemAppearance(); createMainWindow(); - setGlobalShortcuts(); + setGlobalShortcuts(appSettings); subscribePowerEvents(); deleteOldTempFiles(); hookRequestHeaders(); @@ -395,24 +395,27 @@ function notifyOpenFile() { } } -function setGlobalShortcuts() { +function setGlobalShortcuts(appSettings) { const defaultShortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+'; const defaultShortcuts = { + AutoType: { shortcut: defaultShortcutModifiers + 'T', event: 'auto-type' }, CopyPassword: { shortcut: defaultShortcutModifiers + 'C', event: 'copy-password' }, CopyUser: { shortcut: defaultShortcutModifiers + 'B', event: 'copy-user' }, CopyUrl: { shortcut: defaultShortcutModifiers + 'U', event: 'copy-url' }, - AutoType: { shortcut: defaultShortcutModifiers + 'T', event: 'auto-type' } + CopyOtp: { event: 'copy-otp' } }; electron.globalShortcut.unregisterAll(); for (const [key, shortcutDef] of Object.entries(defaultShortcuts)) { const fromSettings = appSettings[`globalShortcut${key}`]; const shortcut = fromSettings || shortcutDef.shortcut; const eventName = shortcutDef.event; - try { - electron.globalShortcut.register(shortcut, () => { - emitRemoteEvent(eventName); - }); - } catch (e) {} + if (shortcut) { + try { + electron.globalShortcut.register(shortcut, () => { + emitRemoteEvent(eventName); + }); + } catch (e) {} + } } } diff --git a/release-notes.md b/release-notes.md index 869e0d96..1a41cf2b 100644 --- a/release-notes.md +++ b/release-notes.md @@ -3,6 +3,7 @@ Release notes ##### v1.12.0 (TBD) `-` #1022: fuzzy search `+` #1108: setting for running in an iframe +`+` #963: keyboard shortcut to copy OTP in background `-` fix #1273: untranslated menu items ##### v1.11.6 (2019-10-04)