mirror of https://github.com/keeweb/keeweb.git
fixed yubikey totp auto-type
This commit is contained in:
parent
5a94c81b11
commit
96ee68dee7
|
@ -142,8 +142,9 @@ AutoTypeRunner.Substitutions = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
AutoTypeRunner.prototype.resolve = function(entry, callback) {
|
AutoTypeRunner.prototype.resolve = function(entry, context, callback) {
|
||||||
this.entry = entry;
|
this.entry = entry;
|
||||||
|
this.context = context;
|
||||||
try {
|
try {
|
||||||
this.resolveOps(this.ops);
|
this.resolveOps(this.ops);
|
||||||
if (!this.pendingResolvesCount) {
|
if (!this.pendingResolvesCount) {
|
||||||
|
@ -203,6 +204,11 @@ AutoTypeRunner.prototype.resolveOp = function(op) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.context && this.context.resolved && this.context.resolved[lowerValue]) {
|
||||||
|
op.type = 'text';
|
||||||
|
op.value = this.context.resolved[lowerValue];
|
||||||
|
return;
|
||||||
|
}
|
||||||
const substitution = AutoTypeRunner.Substitutions[lowerValue];
|
const substitution = AutoTypeRunner.Substitutions[lowerValue];
|
||||||
if (substitution) {
|
if (substitution) {
|
||||||
// {title}
|
// {title}
|
||||||
|
@ -363,8 +369,8 @@ AutoTypeRunner.prototype.getOtp = function(op) {
|
||||||
if (!this.entry.otpGenerator) {
|
if (!this.entry.otpGenerator) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
this.entry.otpGenerator.next(otp => {
|
this.entry.otpGenerator.next((err, otp) => {
|
||||||
this.pendingResolved(op, otp, otp ? undefined : 'OTP error');
|
this.pendingResolved(op, otp, err);
|
||||||
});
|
});
|
||||||
return AutoTypeRunner.PendingResolve;
|
return AutoTypeRunner.PendingResolve;
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@ const AutoType = {
|
||||||
handleEvent(e) {
|
handleEvent(e) {
|
||||||
const entry = (e && e.entry) || null;
|
const entry = (e && e.entry) || null;
|
||||||
const sequence = (e && e.sequence) || null;
|
const sequence = (e && e.sequence) || null;
|
||||||
|
const context = (e && e.context) || null;
|
||||||
logger.debug('Auto type event', entry);
|
logger.debug('Auto type event', entry);
|
||||||
if (this.running) {
|
if (this.running) {
|
||||||
logger.debug('Already running, skipping event');
|
logger.debug('Already running, skipping event');
|
||||||
|
@ -41,7 +42,7 @@ const AutoType = {
|
||||||
}
|
}
|
||||||
if (entry) {
|
if (entry) {
|
||||||
this.hideWindow(() => {
|
this.hideWindow(() => {
|
||||||
this.runAndHandleResult({ entry, sequence });
|
this.runAndHandleResult({ entry, sequence, context });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.selectEntryView) {
|
if (this.selectEntryView) {
|
||||||
|
@ -76,13 +77,14 @@ const AutoType = {
|
||||||
run(result, callback) {
|
run(result, callback) {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
const sequence = result.sequence || result.entry.getEffectiveAutoTypeSeq();
|
const sequence = result.sequence || result.entry.getEffectiveAutoTypeSeq();
|
||||||
|
const context = result.context;
|
||||||
logger.debug('Start', sequence);
|
logger.debug('Start', sequence);
|
||||||
const ts = logger.ts();
|
const ts = logger.ts();
|
||||||
try {
|
try {
|
||||||
const parser = new AutoTypeParser(sequence);
|
const parser = new AutoTypeParser(sequence);
|
||||||
const runner = parser.parse();
|
const runner = parser.parse();
|
||||||
logger.debug('Parsed', this.printOps(runner.ops));
|
logger.debug('Parsed', this.printOps(runner.ops));
|
||||||
runner.resolve(result.entry, err => {
|
runner.resolve(result.entry, context, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.running = false;
|
this.running = false;
|
||||||
logger.error('Resolve error', err);
|
logger.error('Resolve error', err);
|
||||||
|
@ -120,7 +122,7 @@ const AutoType = {
|
||||||
try {
|
try {
|
||||||
const parser = new AutoTypeParser(sequence);
|
const parser = new AutoTypeParser(sequence);
|
||||||
const runner = parser.parse();
|
const runner = parser.parse();
|
||||||
runner.resolve(entry, callback);
|
runner.resolve(entry, null, callback);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
return callback(ex);
|
return callback(ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ class DetailsView extends View {
|
||||||
this.onKey(Keys.DOM_VK_B, this.copyUserName, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_B, this.copyUserName, KeyHandler.SHORTCUT_ACTION);
|
||||||
this.onKey(Keys.DOM_VK_U, this.copyUrl, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_U, this.copyUrl, KeyHandler.SHORTCUT_ACTION);
|
||||||
if (AutoType.enabled) {
|
if (AutoType.enabled) {
|
||||||
this.onKey(Keys.DOM_VK_T, this.autoType, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_T, () => this.autoType(), KeyHandler.SHORTCUT_ACTION);
|
||||||
}
|
}
|
||||||
this.onKey(
|
this.onKey(
|
||||||
Keys.DOM_VK_DELETE,
|
Keys.DOM_VK_DELETE,
|
||||||
|
@ -153,7 +153,7 @@ class DetailsView extends View {
|
||||||
fieldView.render();
|
fieldView.render();
|
||||||
fieldView.on('change', this.fieldChanged.bind(this));
|
fieldView.on('change', this.fieldChanged.bind(this));
|
||||||
fieldView.on('copy', this.fieldCopied.bind(this));
|
fieldView.on('copy', this.fieldCopied.bind(this));
|
||||||
fieldView.on('autotype', this.fieldAutoType.bind(this));
|
fieldView.on('autotype', e => this.autoType(e.source.model.sequence));
|
||||||
if (hideEmptyFields) {
|
if (hideEmptyFields) {
|
||||||
const value = fieldView.model.value();
|
const value = fieldView.model.value();
|
||||||
if (!value || value.length === 0 || value.byteLength === 0) {
|
if (!value || value.length === 0 || value.byteLength === 0) {
|
||||||
|
@ -486,15 +486,15 @@ class DetailsView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
copyOtp() {
|
copyOtp() {
|
||||||
const otpFieldView = this.getFieldView('$otp');
|
const otpField = this.getFieldView('$otp');
|
||||||
if (this.model.external) {
|
if (this.model.external) {
|
||||||
if (!otpFieldView) {
|
if (!otpField) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
otpFieldView.copyValue();
|
otpField.copyValue();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.copyKeyPress(otpFieldView);
|
this.copyKeyPress(otpField);
|
||||||
}
|
}
|
||||||
|
|
||||||
showCopyTip() {
|
showCopyTip() {
|
||||||
|
@ -946,15 +946,22 @@ class DetailsView extends View {
|
||||||
this.views.autoType.render();
|
this.views.autoType.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
autoType() {
|
autoType(sequence) {
|
||||||
Events.emit('auto-type', { entry: this.model });
|
const entry = this.model;
|
||||||
}
|
if (entry.external && (!sequence || sequence.includes('{TOTP}'))) {
|
||||||
|
const otpField = this.getFieldView('$otp');
|
||||||
fieldAutoType(e) {
|
otpField.refreshOtp(err => {
|
||||||
Events.emit('auto-type', {
|
if (!err) {
|
||||||
entry: this.model,
|
Events.emit('auto-type', {
|
||||||
sequence: e.source.model.sequence
|
entry,
|
||||||
});
|
sequence,
|
||||||
|
context: { resolved: { totp: otpField.otpValue } }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Events.emit('auto-type', { entry, sequence });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,17 +153,22 @@ class FieldViewOtp extends FieldViewText {
|
||||||
}
|
}
|
||||||
|
|
||||||
copyValue() {
|
copyValue() {
|
||||||
|
this.refreshOtp(err => {
|
||||||
|
if (!err) {
|
||||||
|
super.copyValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshOtp(callback) {
|
||||||
if (this.model.needsTouch) {
|
if (this.model.needsTouch) {
|
||||||
if (this.otpValue) {
|
if (this.otpValue) {
|
||||||
return super.copyValue();
|
callback();
|
||||||
|
} else {
|
||||||
|
this.requestTouch(callback);
|
||||||
}
|
}
|
||||||
this.requestTouch(err => {
|
|
||||||
if (!err) {
|
|
||||||
super.copyValue();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
super.copyValue();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue