mirror of
https://github.com/keeweb/keeweb.git
synced 2024-06-26 07:39:04 +02:00
listing YubiKeys on the open view
This commit is contained in:
parent
f215c26a63
commit
93310eb029
|
@ -80,9 +80,13 @@ const YubiKey = {
|
||||||
const yubiKeysIncludingEmpty = stdout
|
const yubiKeysIncludingEmpty = stdout
|
||||||
.trim()
|
.trim()
|
||||||
.split(/\n/g)
|
.split(/\n/g)
|
||||||
.map(line => (line.match(/\d{5,}$/g) || [])[0]);
|
.map(line => {
|
||||||
|
const fullName = line;
|
||||||
|
const serial = (line.match(/\d{5,}$/g) || [])[0];
|
||||||
|
return { fullName, serial };
|
||||||
|
});
|
||||||
|
|
||||||
const yubiKeys = yubiKeysIncludingEmpty.filter(s => s);
|
const yubiKeys = yubiKeysIncludingEmpty.filter(s => s.serial);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
yubiKeysIncludingEmpty.length === 1 &&
|
yubiKeysIncludingEmpty.length === 1 &&
|
||||||
|
|
|
@ -233,6 +233,12 @@
|
||||||
"openListErrorBody": "There was an error loading file list",
|
"openListErrorBody": "There was an error loading file list",
|
||||||
"openShowAllFiles": "Show all files",
|
"openShowAllFiles": "Show all files",
|
||||||
"openFileNoCacheError": "File not found in the cache storage. This can happen because browser storage was cleaned up. To open the file, remove it from KeeWeb and add it again.",
|
"openFileNoCacheError": "File not found in the cache storage. This can happen because browser storage was cleaned up. To open the file, remove it from KeeWeb and add it again.",
|
||||||
|
"openChalRespHeader": "Challenge-Response",
|
||||||
|
"openChalRespLoading": "Loading the list of YubiKeys",
|
||||||
|
"openChalRespSelectYubiKey": "Select a YubiKey that you would like to use",
|
||||||
|
"openChalRespErrorNotInstalled": "YubiKey integration is not configured, please go to settings to set it up",
|
||||||
|
"openChalRespErrorEmpty": "No YubiKeys found",
|
||||||
|
"openChalRespSlot": "slot",
|
||||||
|
|
||||||
"detAttDownload": "Shift-click the attachment button to download it or",
|
"detAttDownload": "Shift-click the attachment button to download it or",
|
||||||
"detAttDelToRemove": "Delete to remove",
|
"detAttDelToRemove": "Delete to remove",
|
||||||
|
|
|
@ -35,7 +35,7 @@ class YubiKeyOtpModel extends ExternalOtpDeviceModel {
|
||||||
const openErrors = [];
|
const openErrors = [];
|
||||||
const openNextYubiKey = () => {
|
const openNextYubiKey = () => {
|
||||||
const yubiKey = yubiKeys.shift();
|
const yubiKey = yubiKeys.shift();
|
||||||
this._addYubiKey(yubiKey, err => {
|
this._addYubiKey(yubiKey.serial, err => {
|
||||||
if (YubiKey.aborted) {
|
if (YubiKey.aborted) {
|
||||||
return callback('Aborted');
|
return callback('Aborted');
|
||||||
}
|
}
|
||||||
|
|
65
app/scripts/views/open-chal-resp-view.js
Normal file
65
app/scripts/views/open-chal-resp-view.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import { View } from 'framework/views/view';
|
||||||
|
import { YubiKey } from 'comp/app/yubikey';
|
||||||
|
import { Locale } from 'util/locale';
|
||||||
|
import template from 'templates/open-chal-resp.hbs';
|
||||||
|
|
||||||
|
class OpenChalRespView extends View {
|
||||||
|
template = template;
|
||||||
|
|
||||||
|
events = {
|
||||||
|
'click .open-chal-resp__item': 'itemClick'
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
YubiKey.checkToolStatus().then(status => {
|
||||||
|
if (this.removed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (status === 'ok') {
|
||||||
|
YubiKey.list((err, yubiKeys) => {
|
||||||
|
this.error = err;
|
||||||
|
this.yubiKeys = [];
|
||||||
|
for (const { fullName, serial } of yubiKeys) {
|
||||||
|
for (const slot of [1, 2]) {
|
||||||
|
this.yubiKeys.push({
|
||||||
|
fullName,
|
||||||
|
serial,
|
||||||
|
slot
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.render();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let error = this.error;
|
||||||
|
|
||||||
|
if (YubiKey.ykmanStatus === 'error') {
|
||||||
|
error = Locale.openChalRespErrorNotInstalled.replace('{}', 'ykman');
|
||||||
|
}
|
||||||
|
if (this.yubiKeys && !this.yubiKeys.length) {
|
||||||
|
error = Locale.openChalRespErrorEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.render({
|
||||||
|
error,
|
||||||
|
yubiKeys: this.yubiKeys,
|
||||||
|
loading: !YubiKey.ykmanStatus || YubiKey.ykmanStatus === 'checking'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
itemClick(e) {
|
||||||
|
const el = e.target.closest('[data-serial]');
|
||||||
|
const { serial, slot } = el.dataset;
|
||||||
|
this.emit('select', { serial, slot });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { OpenChalRespView };
|
|
@ -19,6 +19,7 @@ import { Logger } from 'util/logger';
|
||||||
import { InputFx } from 'util/ui/input-fx';
|
import { InputFx } from 'util/ui/input-fx';
|
||||||
import { OpenConfigView } from 'views/open-config-view';
|
import { OpenConfigView } from 'views/open-config-view';
|
||||||
import { StorageFileListView } from 'views/storage-file-list-view';
|
import { StorageFileListView } from 'views/storage-file-list-view';
|
||||||
|
import { OpenChalRespView } from 'views/open-chal-resp-view';
|
||||||
import { omit } from 'util/fn';
|
import { omit } from 'util/fn';
|
||||||
import { GeneratorView } from 'views/generator-view';
|
import { GeneratorView } from 'views/generator-view';
|
||||||
import template from 'templates/open.hbs';
|
import template from 'templates/open.hbs';
|
||||||
|
@ -1043,16 +1044,19 @@ class OpenView extends View {
|
||||||
if (this.busy) {
|
if (this.busy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.busy = true;
|
|
||||||
YubiKey.checkToolStatus().then(status => {
|
|
||||||
if (status !== 'ok') {
|
|
||||||
this.busy = false;
|
|
||||||
return Events.emit('toggle-settings', 'devices');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.busy = false;
|
const chalRespView = new OpenChalRespView();
|
||||||
|
chalRespView.on('select', e => {
|
||||||
|
// console.log('e', e.serial, e.slot);
|
||||||
|
});
|
||||||
|
|
||||||
Alerts.notImplemented();
|
Alerts.alert({
|
||||||
|
header: Locale.openChalRespHeader,
|
||||||
|
icon: 'exchange',
|
||||||
|
buttons: [{ result: '', title: Locale.alertCancel }],
|
||||||
|
esc: '',
|
||||||
|
click: '',
|
||||||
|
view: chalRespView
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,3 +388,19 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.open-chal-resp {
|
||||||
|
&__head {
|
||||||
|
padding: $base-padding;
|
||||||
|
}
|
||||||
|
&__icon {
|
||||||
|
margin-right: $small-spacing;
|
||||||
|
}
|
||||||
|
&__item {
|
||||||
|
padding: $base-padding;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--action-background-color-focus-tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
app/templates/open-chal-resp.hbs
Normal file
20
app/templates/open-chal-resp.hbs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<div class="open-chal-resp">
|
||||||
|
{{#if loading}}
|
||||||
|
<div class="open-chal-resp__head">
|
||||||
|
<i class="open-chal-resp__icon fa fa-spinner fa-spin"></i> {{res 'openChalRespLoading'}}
|
||||||
|
</div>
|
||||||
|
{{else if error}}
|
||||||
|
<div class="open-chal-resp__head">
|
||||||
|
<i class="open-chal-resp__icon fa fa-ban"></i> {{error}}
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="open-chal-resp__head">{{res 'openChalRespSelectYubiKey'}}:</div>
|
||||||
|
<div>
|
||||||
|
{{#each yubiKeys as |yk|}}
|
||||||
|
<div class="open-chal-resp__item" data-serial="{{yk.serial}}" data-slot="{{yk.slot}}">
|
||||||
|
{{yk.fullName}}, {{res 'openChalRespSlot'}} {{yk.slot}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user