keeweb/app/scripts/comp/app/usb-listener.js

111 lines
3.0 KiB
JavaScript
Raw Normal View History

2020-04-15 16:50:01 +02:00
import { Events } from 'framework/events';
import { Logger } from 'util/logger';
import { Launcher } from 'comp/launcher';
import { AppSettingsModel } from 'models/app-settings-model';
2020-05-05 17:57:01 +02:00
import { YubiKeyVendorId } from 'const/hardware';
2020-05-05 18:01:16 +02:00
import { Features } from 'util/features';
2020-04-15 16:50:01 +02:00
const logger = new Logger('usb-listener');
const UsbListener = {
supported: Features.isDesktop,
attachedYubiKeys: [],
2020-04-15 16:50:01 +02:00
init() {
2020-05-05 18:01:16 +02:00
if (!this.supported) {
2020-04-15 16:50:01 +02:00
return;
}
AppSettingsModel.on('change:enableUsb', (model, enabled) => {
if (enabled) {
this.start();
} else {
this.stop();
}
});
if (AppSettingsModel.enableUsb) {
this.start();
}
},
start() {
logger.info('Starting USB listener');
if (this.usb) {
this.stop();
}
try {
const ts = logger.ts();
this.usb = Launcher.reqNative('usb');
2020-04-15 16:50:01 +02:00
this.listen();
this.attachedYubiKeys = this.usb
2020-04-15 16:50:01 +02:00
.getDeviceList()
.filter(this.isYubiKey)
2020-06-01 16:53:51 +02:00
.map((device) => ({ device }));
2020-04-15 16:50:01 +02:00
if (this.attachedYubiKeys.length > 0) {
logger.info(`${this.attachedYubiKeys.length} YubiKey(s) found`, logger.ts(ts));
Events.emit('usb-devices-changed');
}
} catch (e) {
logger.error('Error loading USB module', e);
}
},
stop() {
logger.info('Stopping USB listener');
if (this.usb) {
if (this.attachedYubiKeys.length) {
this.attachedYubiKeys = [];
Events.emit('usb-devices-changed');
}
2020-05-22 10:44:59 +02:00
this.usb.off('attach', UsbListener.deviceAttached);
this.usb.off('detach', UsbListener.deviceDetached);
2020-04-15 16:50:01 +02:00
this.usb = null;
}
},
listen() {
2020-05-22 10:44:59 +02:00
this.usb.on('attach', UsbListener.deviceAttached);
this.usb.on('detach', UsbListener.deviceDetached);
},
2020-04-15 16:50:01 +02:00
2020-05-22 10:44:59 +02:00
deviceAttached(device) {
if (UsbListener.isYubiKey(device)) {
UsbListener.attachedYubiKeys.push({ device });
logger.info(`YubiKey attached, total: ${UsbListener.attachedYubiKeys.length}`, device);
Events.emit('usb-devices-changed');
}
},
deviceDetached(device) {
if (UsbListener.isYubiKey(device)) {
const index = UsbListener.attachedYubiKeys.findIndex(
2020-06-01 16:53:51 +02:00
(yk) => yk.device.deviceAddress === device.deviceAddress
2020-05-22 10:44:59 +02:00
);
if (index >= 0) {
UsbListener.attachedYubiKeys.splice(index, 1);
logger.info(
`YubiKey detached, total: ${UsbListener.attachedYubiKeys.length}`,
device
2020-04-15 16:50:01 +02:00
);
2020-05-22 10:44:59 +02:00
Events.emit('usb-devices-changed');
2020-04-15 16:50:01 +02:00
}
2020-05-22 10:44:59 +02:00
}
2020-04-15 16:50:01 +02:00
},
isYubiKey(device) {
return device.deviceDescriptor.idVendor === YubiKeyVendorId;
}
};
export { UsbListener };