fix #963: keyboard shortcut to copy OTP in background

This commit is contained in:
antelle 2019-10-06 08:48:11 +02:00
parent 63aee0e876
commit cc9e369b6f
7 changed files with 41 additions and 21 deletions

View File

@ -23,6 +23,7 @@ const globalShortcuts = {
copyPassword: { mac: 'Ctrl+Alt+C', all: 'Shift+Alt+C' }, copyPassword: { mac: 'Ctrl+Alt+C', all: 'Shift+Alt+C' },
copyUser: { mac: 'Ctrl+Alt+B', all: 'Shift+Alt+B' }, copyUser: { mac: 'Ctrl+Alt+B', all: 'Shift+Alt+B' },
copyUrl: { mac: 'Ctrl+Alt+U', all: 'Shift+Alt+U' }, copyUrl: { mac: 'Ctrl+Alt+U', all: 'Shift+Alt+U' },
copyOtp: {},
autoType: { mac: 'Ctrl+Alt+T', all: 'Shift+Alt+T' } autoType: { mac: 'Ctrl+Alt+T', all: 'Shift+Alt+T' }
}; };
@ -48,6 +49,9 @@ const Shortcuts = {
}; };
}, },
presentShortcut(shortcutValue, formatting) { presentShortcut(shortcutValue, formatting) {
if (!shortcutValue) {
return '-';
}
return shortcutValue return shortcutValue
.split(/\+/g) .split(/\+/g)
.map(part => { .map(part => {

View File

@ -518,6 +518,7 @@
"setShCopyPassGlobal": "copy password (when the app is in background)", "setShCopyPassGlobal": "copy password (when the app is in background)",
"setShCopyUserGlobal": "copy user (when the app is in background)", "setShCopyUserGlobal": "copy user (when the app is in background)",
"setShCopyUrlGlobal": "copy website (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)", "setShAutoTypeGlobal": "auto-type (when the app is in background)",
"setShLock": "lock database", "setShLock": "lock database",
"setShEdit": "Press a new key combination to set it as shortcut", "setShEdit": "Press a new key combination to set it as shortcut",

View File

@ -45,6 +45,7 @@ class DetailsView extends View {
passEditView = null; passEditView = null;
userEditView = null; userEditView = null;
urlEditView = null; urlEditView = null;
otpEditView = null;
fieldCopyTip = null; fieldCopyTip = null;
events = { events = {
@ -71,6 +72,7 @@ class DetailsView extends View {
this.listenTo(Events, 'copy-password', this.copyPassword); this.listenTo(Events, 'copy-password', this.copyPassword);
this.listenTo(Events, 'copy-user', this.copyUserName); this.listenTo(Events, 'copy-user', this.copyUserName);
this.listenTo(Events, 'copy-url', this.copyUrl); this.listenTo(Events, 'copy-url', this.copyUrl);
this.listenTo(Events, 'copy-otp', this.copyOtp);
this.listenTo(Events, 'toggle-settings', this.settingsToggled); this.listenTo(Events, 'toggle-settings', this.settingsToggled);
this.listenTo(Events, 'context-menu-select', this.contextMenuSelect); this.listenTo(Events, 'context-menu-select', this.contextMenuSelect);
this.listenTo(Events, 'set-locale', this.render); 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)) { for (const field of Object.keys(model.fields)) {
if (field === 'otp' && this.model.otpGenerator) { if (field === 'otp' && this.model.otpGenerator) {
this.fieldViews.push( this.otpEditView = new FieldViewOtp({
new FieldViewOtp({ name: '$' + field,
name: '$' + field, title: field,
title: field, value() {
value() { return model.otpGenerator;
return model.otpGenerator; },
}, sequence: '{TOTP}'
sequence: '{TOTP}' });
}) this.fieldViews.push(this.otpEditView);
);
} else { } else {
this.fieldViews.push( this.fieldViews.push(
new FieldViewCustom({ new FieldViewCustom({
@ -594,7 +596,7 @@ class DetailsView extends View {
return false; return false;
} }
if (!window.getSelection().toString()) { if (!window.getSelection().toString()) {
const fieldValue = editView.value; const fieldValue = editView.otpValue || editView.value;
const fieldText = const fieldText =
fieldValue && fieldValue.isProtected ? fieldValue.getText() : fieldValue; fieldValue && fieldValue.isProtected ? fieldValue.getText() : fieldValue;
if (!fieldText) { if (!fieldText) {
@ -629,6 +631,12 @@ class DetailsView extends View {
this.copyKeyPress(this.urlEditView); this.copyKeyPress(this.urlEditView);
} }
copyOtp() {
if (this.otpEditView) {
this.copyKeyPress(this.otpEditView);
}
}
showCopyTip() { showCopyTip() {
if (this.helpTipCopyShown) { if (this.helpTipCopyShown) {
return; return;

View File

@ -39,10 +39,11 @@ class SettingsShortcutsView extends View {
autoTypeSupported: !!Launcher, autoTypeSupported: !!Launcher,
globalShortcuts: Launcher globalShortcuts: Launcher
? { ? {
autoType: Shortcuts.globalShortcutText('autoType', true),
copyPassword: Shortcuts.globalShortcutText('copyPassword', true), copyPassword: Shortcuts.globalShortcutText('copyPassword', true),
copyUser: Shortcuts.globalShortcutText('copyUser', true), copyUser: Shortcuts.globalShortcutText('copyUser', true),
copyUrl: Shortcuts.globalShortcutText('copyUrl', true), copyUrl: Shortcuts.globalShortcutText('copyUrl', true),
autoType: Shortcuts.globalShortcutText('autoType', true) copyOtp: Shortcuts.globalShortcutText('copyOtp', true)
} }
: undefined : undefined
}); });

View File

@ -20,6 +20,8 @@
<div><span class="shortcut">{{{cmd}}},</span> {{res 'setShSet'}}</div> <div><span class="shortcut">{{{cmd}}},</span> {{res 'setShSet'}}</div>
<div><span class="shortcut">{{{cmd}}}L</span> {{res 'setShLock'}}</div> <div><span class="shortcut">{{{cmd}}}L</span> {{res 'setShLock'}}</div>
{{#if globalShortcuts}} {{#if globalShortcuts}}
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
data-shortcut="autoType">{{{globalShortcuts.autoType}}}</button> {{res 'setShAutoTypeGlobal'}}</div>
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}" <div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
data-shortcut="copyPassword">{{{globalShortcuts.copyPassword}}}</button> {{res 'setShCopyPassGlobal'}}</div> data-shortcut="copyPassword">{{{globalShortcuts.copyPassword}}}</button> {{res 'setShCopyPassGlobal'}}</div>
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}" <div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
@ -27,6 +29,6 @@
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}" <div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
data-shortcut="copyUrl">{{{globalShortcuts.copyUrl}}}</button> {{res 'setShCopyUrlGlobal'}}</div> data-shortcut="copyUrl">{{{globalShortcuts.copyUrl}}}</button> {{res 'setShCopyUrlGlobal'}}</div>
<div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}" <div><button class="shortcut btn-silent {{#if globalIsLarge}}shortcut-large{{/if}}"
data-shortcut="autoType">{{{globalShortcuts.autoType}}}</button> {{res 'setShAutoTypeGlobal'}}</div> data-shortcut="copyOtp">{{{globalShortcuts.copyOtp}}}</button> {{res 'setShCopyOtpGlobal'}}</div>
{{/if}} {{/if}}
</div> </div>

View File

@ -67,7 +67,7 @@ app.on('ready', () => {
setAppOptions(); setAppOptions();
setSystemAppearance(); setSystemAppearance();
createMainWindow(); createMainWindow();
setGlobalShortcuts(); setGlobalShortcuts(appSettings);
subscribePowerEvents(); subscribePowerEvents();
deleteOldTempFiles(); deleteOldTempFiles();
hookRequestHeaders(); hookRequestHeaders();
@ -395,24 +395,27 @@ function notifyOpenFile() {
} }
} }
function setGlobalShortcuts() { function setGlobalShortcuts(appSettings) {
const defaultShortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+'; const defaultShortcutModifiers = process.platform === 'darwin' ? 'Ctrl+Alt+' : 'Shift+Alt+';
const defaultShortcuts = { const defaultShortcuts = {
AutoType: { shortcut: defaultShortcutModifiers + 'T', event: 'auto-type' },
CopyPassword: { shortcut: defaultShortcutModifiers + 'C', event: 'copy-password' }, CopyPassword: { shortcut: defaultShortcutModifiers + 'C', event: 'copy-password' },
CopyUser: { shortcut: defaultShortcutModifiers + 'B', event: 'copy-user' }, CopyUser: { shortcut: defaultShortcutModifiers + 'B', event: 'copy-user' },
CopyUrl: { shortcut: defaultShortcutModifiers + 'U', event: 'copy-url' }, CopyUrl: { shortcut: defaultShortcutModifiers + 'U', event: 'copy-url' },
AutoType: { shortcut: defaultShortcutModifiers + 'T', event: 'auto-type' } CopyOtp: { event: 'copy-otp' }
}; };
electron.globalShortcut.unregisterAll(); electron.globalShortcut.unregisterAll();
for (const [key, shortcutDef] of Object.entries(defaultShortcuts)) { for (const [key, shortcutDef] of Object.entries(defaultShortcuts)) {
const fromSettings = appSettings[`globalShortcut${key}`]; const fromSettings = appSettings[`globalShortcut${key}`];
const shortcut = fromSettings || shortcutDef.shortcut; const shortcut = fromSettings || shortcutDef.shortcut;
const eventName = shortcutDef.event; const eventName = shortcutDef.event;
try { if (shortcut) {
electron.globalShortcut.register(shortcut, () => { try {
emitRemoteEvent(eventName); electron.globalShortcut.register(shortcut, () => {
}); emitRemoteEvent(eventName);
} catch (e) {} });
} catch (e) {}
}
} }
} }

View File

@ -3,6 +3,7 @@ Release notes
##### v1.12.0 (TBD) ##### v1.12.0 (TBD)
`-` #1022: fuzzy search `-` #1022: fuzzy search
`+` #1108: setting for running in an iframe `+` #1108: setting for running in an iframe
`+` #963: keyboard shortcut to copy OTP in background
`-` fix #1273: untranslated menu items `-` fix #1273: untranslated menu items
##### v1.11.6 (2019-10-04) ##### v1.11.6 (2019-10-04)