mirror of https://github.com/keeweb/keeweb.git
fix #963: keyboard shortcut to copy OTP in background
This commit is contained in:
parent
63aee0e876
commit
cc9e369b6f
|
@ -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 => {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue