1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports["default"] = void 0;
|
7 |
|
8 | var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
9 |
|
10 | var _events = _interopRequireDefault(require("events"));
|
11 |
|
12 | var _debugDecorator = require("../debug-decorator");
|
13 |
|
14 | var _class, _temp;
|
15 |
|
16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
17 |
|
18 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
19 |
|
20 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
21 |
|
22 | function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
23 |
|
24 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
25 |
|
26 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
27 |
|
28 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
29 |
|
30 | function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }
|
31 |
|
32 | var T1HID_VENDOR = 0x534c;
|
33 | var TREZOR_DESCS = [
|
34 |
|
35 | {
|
36 | vendorId: 0x534c,
|
37 | productId: 0x0001
|
38 | },
|
39 | {
|
40 | vendorId: 0x1209,
|
41 | productId: 0x53c0
|
42 | },
|
43 | {
|
44 | vendorId: 0x1209,
|
45 | productId: 0x53c1
|
46 | }];
|
47 | var CONFIGURATION_ID = 1;
|
48 | var INTERFACE_ID = 0;
|
49 | var ENDPOINT_ID = 1;
|
50 | var DEBUG_INTERFACE_ID = 1;
|
51 | var DEBUG_ENDPOINT_ID = 2;
|
52 | var WebUsbPlugin = (_class = (_temp =
|
53 |
|
54 | function () {
|
55 | function WebUsbPlugin() {
|
56 | _classCallCheck(this, WebUsbPlugin);
|
57 |
|
58 | this.name = "WebUsbPlugin";
|
59 | this.version = "1.6.5";
|
60 | this.debug = false;
|
61 | this.allowsWriteAndEnumerate = true;
|
62 | this.configurationId = CONFIGURATION_ID;
|
63 | this.normalInterfaceId = INTERFACE_ID;
|
64 | this.normalEndpointId = ENDPOINT_ID;
|
65 | this.debugInterfaceId = DEBUG_INTERFACE_ID;
|
66 | this.debugEndpointId = DEBUG_ENDPOINT_ID;
|
67 | this.unreadableHidDevice = false;
|
68 | this.unreadableHidDeviceChange = new _events["default"]();
|
69 | this._lastDevices = [];
|
70 | this.requestNeeded = true;
|
71 | }
|
72 |
|
73 | _createClass(WebUsbPlugin, [{
|
74 | key: "init",
|
75 | value: function () {
|
76 | var _init = _asyncToGenerator(
|
77 |
|
78 | _regenerator["default"].mark(function _callee(debug) {
|
79 | var usb;
|
80 | return _regenerator["default"].wrap(function _callee$(_context) {
|
81 | while (1) {
|
82 | switch (_context.prev = _context.next) {
|
83 | case 0:
|
84 | this.debug = !!debug;
|
85 |
|
86 | usb = navigator.usb;
|
87 |
|
88 | if (!(usb == null)) {
|
89 | _context.next = 6;
|
90 | break;
|
91 | }
|
92 |
|
93 | throw new Error("WebUSB is not available on this browser.");
|
94 |
|
95 | case 6:
|
96 | this.usb = usb;
|
97 |
|
98 | case 7:
|
99 | case "end":
|
100 | return _context.stop();
|
101 | }
|
102 | }
|
103 | }, _callee, this);
|
104 | }));
|
105 |
|
106 | function init(_x) {
|
107 | return _init.apply(this, arguments);
|
108 | }
|
109 |
|
110 | return init;
|
111 | }()
|
112 | }, {
|
113 | key: "_deviceHasDebugLink",
|
114 | value: function _deviceHasDebugLink(device) {
|
115 | try {
|
116 | var iface = device.configurations[0].interfaces[DEBUG_INTERFACE_ID].alternates[0];
|
117 | return iface.interfaceClass === 255 && iface.endpoints[0].endpointNumber === DEBUG_ENDPOINT_ID;
|
118 | } catch (e) {
|
119 | return false;
|
120 | }
|
121 | }
|
122 | }, {
|
123 | key: "_deviceIsHid",
|
124 | value: function _deviceIsHid(device) {
|
125 | return device.vendorId === T1HID_VENDOR;
|
126 | }
|
127 | }, {
|
128 | key: "_listDevices",
|
129 | value: function () {
|
130 | var _listDevices2 = _asyncToGenerator(
|
131 |
|
132 | _regenerator["default"].mark(function _callee2() {
|
133 | var _this = this;
|
134 |
|
135 | var bootloaderId, devices, trezorDevices, hidDevices, nonHidDevices, oldUnreadableHidDevice;
|
136 | return _regenerator["default"].wrap(function _callee2$(_context2) {
|
137 | while (1) {
|
138 | switch (_context2.prev = _context2.next) {
|
139 | case 0:
|
140 | bootloaderId = 0;
|
141 | _context2.next = 3;
|
142 | return this.usb.getDevices();
|
143 |
|
144 | case 3:
|
145 | devices = _context2.sent;
|
146 | trezorDevices = devices.filter(function (dev) {
|
147 | var isTrezor = TREZOR_DESCS.some(function (desc) {
|
148 | return dev.vendorId === desc.vendorId && dev.productId === desc.productId;
|
149 | });
|
150 | return isTrezor;
|
151 | });
|
152 | hidDevices = trezorDevices.filter(function (dev) {
|
153 | return _this._deviceIsHid(dev);
|
154 | });
|
155 | nonHidDevices = trezorDevices.filter(function (dev) {
|
156 | return !_this._deviceIsHid(dev);
|
157 | });
|
158 | this._lastDevices = nonHidDevices.map(function (device) {
|
159 |
|
160 |
|
161 | var serialNumber = device.serialNumber;
|
162 | var path = serialNumber == null || serialNumber === "" ? "bootloader" : serialNumber;
|
163 |
|
164 | if (path === "bootloader") {
|
165 | bootloaderId++;
|
166 | path = path + bootloaderId;
|
167 | }
|
168 |
|
169 | var debug = _this._deviceHasDebugLink(device);
|
170 |
|
171 | return {
|
172 | path: path,
|
173 | device: device,
|
174 | debug: debug
|
175 | };
|
176 | });
|
177 | oldUnreadableHidDevice = this.unreadableHidDevice;
|
178 | this.unreadableHidDevice = hidDevices.length > 0;
|
179 |
|
180 | if (oldUnreadableHidDevice !== this.unreadableHidDevice) {
|
181 | this.unreadableHidDeviceChange.emit("change");
|
182 | }
|
183 |
|
184 | return _context2.abrupt("return", this._lastDevices);
|
185 |
|
186 | case 12:
|
187 | case "end":
|
188 | return _context2.stop();
|
189 | }
|
190 | }
|
191 | }, _callee2, this);
|
192 | }));
|
193 |
|
194 | function _listDevices() {
|
195 | return _listDevices2.apply(this, arguments);
|
196 | }
|
197 |
|
198 | return _listDevices;
|
199 | }()
|
200 | }, {
|
201 | key: "enumerate",
|
202 | value: function () {
|
203 | var _enumerate = _asyncToGenerator(
|
204 |
|
205 | _regenerator["default"].mark(function _callee3() {
|
206 | return _regenerator["default"].wrap(function _callee3$(_context3) {
|
207 | while (1) {
|
208 | switch (_context3.prev = _context3.next) {
|
209 | case 0:
|
210 | _context3.next = 2;
|
211 | return this._listDevices();
|
212 |
|
213 | case 2:
|
214 | _context3.t0 = function (info) {
|
215 | return {
|
216 | path: info.path,
|
217 | debug: info.debug
|
218 | };
|
219 | };
|
220 |
|
221 | return _context3.abrupt("return", _context3.sent.map(_context3.t0));
|
222 |
|
223 | case 4:
|
224 | case "end":
|
225 | return _context3.stop();
|
226 | }
|
227 | }
|
228 | }, _callee3, this);
|
229 | }));
|
230 |
|
231 | function enumerate() {
|
232 | return _enumerate.apply(this, arguments);
|
233 | }
|
234 |
|
235 | return enumerate;
|
236 | }()
|
237 | }, {
|
238 | key: "_findDevice",
|
239 | value: function () {
|
240 | var _findDevice2 = _asyncToGenerator(
|
241 |
|
242 | _regenerator["default"].mark(function _callee4(path) {
|
243 | var deviceO;
|
244 | return _regenerator["default"].wrap(function _callee4$(_context4) {
|
245 | while (1) {
|
246 | switch (_context4.prev = _context4.next) {
|
247 | case 0:
|
248 | deviceO = this._lastDevices.find(function (d) {
|
249 | return d.path === path;
|
250 | });
|
251 |
|
252 | if (!(deviceO == null)) {
|
253 | _context4.next = 3;
|
254 | break;
|
255 | }
|
256 |
|
257 | throw new Error("Action was interrupted.");
|
258 |
|
259 | case 3:
|
260 | return _context4.abrupt("return", deviceO.device);
|
261 |
|
262 | case 4:
|
263 | case "end":
|
264 | return _context4.stop();
|
265 | }
|
266 | }
|
267 | }, _callee4, this);
|
268 | }));
|
269 |
|
270 | function _findDevice(_x2) {
|
271 | return _findDevice2.apply(this, arguments);
|
272 | }
|
273 |
|
274 | return _findDevice;
|
275 | }()
|
276 | }, {
|
277 | key: "send",
|
278 | value: function () {
|
279 | var _send = _asyncToGenerator(
|
280 |
|
281 | _regenerator["default"].mark(function _callee5(path, data, debug) {
|
282 | var device, newArray, endpoint;
|
283 | return _regenerator["default"].wrap(function _callee5$(_context5) {
|
284 | while (1) {
|
285 | switch (_context5.prev = _context5.next) {
|
286 | case 0:
|
287 | _context5.next = 2;
|
288 | return this._findDevice(path);
|
289 |
|
290 | case 2:
|
291 | device = _context5.sent;
|
292 | newArray = new Uint8Array(64);
|
293 | newArray[0] = 63;
|
294 | newArray.set(new Uint8Array(data), 1);
|
295 |
|
296 | if (device.opened) {
|
297 | _context5.next = 9;
|
298 | break;
|
299 | }
|
300 |
|
301 | _context5.next = 9;
|
302 | return this.connect(path, debug, false);
|
303 |
|
304 | case 9:
|
305 | endpoint = debug ? this.debugEndpointId : this.normalEndpointId;
|
306 | return _context5.abrupt("return", device.transferOut(endpoint, newArray).then(function () {}));
|
307 |
|
308 | case 11:
|
309 | case "end":
|
310 | return _context5.stop();
|
311 | }
|
312 | }
|
313 | }, _callee5, this);
|
314 | }));
|
315 |
|
316 | function send(_x3, _x4, _x5) {
|
317 | return _send.apply(this, arguments);
|
318 | }
|
319 |
|
320 | return send;
|
321 | }()
|
322 | }, {
|
323 | key: "receive",
|
324 | value: function () {
|
325 | var _receive = _asyncToGenerator(
|
326 |
|
327 | _regenerator["default"].mark(function _callee6(path, debug) {
|
328 | var device, endpoint, res;
|
329 | return _regenerator["default"].wrap(function _callee6$(_context6) {
|
330 | while (1) {
|
331 | switch (_context6.prev = _context6.next) {
|
332 | case 0:
|
333 | _context6.next = 2;
|
334 | return this._findDevice(path);
|
335 |
|
336 | case 2:
|
337 | device = _context6.sent;
|
338 | endpoint = debug ? this.debugEndpointId : this.normalEndpointId;
|
339 | _context6.prev = 4;
|
340 |
|
341 | if (device.opened) {
|
342 | _context6.next = 8;
|
343 | break;
|
344 | }
|
345 |
|
346 | _context6.next = 8;
|
347 | return this.connect(path, debug, false);
|
348 |
|
349 | case 8:
|
350 | _context6.next = 10;
|
351 | return device.transferIn(endpoint, 64);
|
352 |
|
353 | case 10:
|
354 | res = _context6.sent;
|
355 |
|
356 | if (!(res.data.byteLength === 0)) {
|
357 | _context6.next = 13;
|
358 | break;
|
359 | }
|
360 |
|
361 | return _context6.abrupt("return", this.receive(path, debug));
|
362 |
|
363 | case 13:
|
364 | return _context6.abrupt("return", res.data.buffer.slice(1));
|
365 |
|
366 | case 16:
|
367 | _context6.prev = 16;
|
368 | _context6.t0 = _context6["catch"](4);
|
369 |
|
370 | if (!(_context6.t0.message === "Device unavailable.")) {
|
371 | _context6.next = 22;
|
372 | break;
|
373 | }
|
374 |
|
375 | throw new Error("Action was interrupted.");
|
376 |
|
377 | case 22:
|
378 | throw _context6.t0;
|
379 |
|
380 | case 23:
|
381 | case "end":
|
382 | return _context6.stop();
|
383 | }
|
384 | }
|
385 | }, _callee6, this, [[4, 16]]);
|
386 | }));
|
387 |
|
388 | function receive(_x6, _x7) {
|
389 | return _receive.apply(this, arguments);
|
390 | }
|
391 |
|
392 | return receive;
|
393 | }()
|
394 | }, {
|
395 | key: "connect",
|
396 | value: function () {
|
397 | var _connect = _asyncToGenerator(
|
398 |
|
399 | _regenerator["default"].mark(function _callee7(path, debug, first) {
|
400 | var _this2 = this;
|
401 |
|
402 | var _loop, i, _ret;
|
403 |
|
404 | return _regenerator["default"].wrap(function _callee7$(_context8) {
|
405 | while (1) {
|
406 | switch (_context8.prev = _context8.next) {
|
407 | case 0:
|
408 | _loop =
|
409 |
|
410 | _regenerator["default"].mark(function _loop(i) {
|
411 | return _regenerator["default"].wrap(function _loop$(_context7) {
|
412 | while (1) {
|
413 | switch (_context7.prev = _context7.next) {
|
414 | case 0:
|
415 | if (!(i > 0)) {
|
416 | _context7.next = 3;
|
417 | break;
|
418 | }
|
419 |
|
420 | _context7.next = 3;
|
421 | return new Promise(function (resolve) {
|
422 | return setTimeout(function () {
|
423 | return resolve();
|
424 | }, i * 200);
|
425 | });
|
426 |
|
427 | case 3:
|
428 | _context7.prev = 3;
|
429 | _context7.next = 6;
|
430 | return _this2._connectIn(path, debug, first);
|
431 |
|
432 | case 6:
|
433 | _context7.t0 = _context7.sent;
|
434 | return _context7.abrupt("return", {
|
435 | v: _context7.t0
|
436 | });
|
437 |
|
438 | case 10:
|
439 | _context7.prev = 10;
|
440 | _context7.t1 = _context7["catch"](3);
|
441 |
|
442 | if (!(i === 4)) {
|
443 | _context7.next = 14;
|
444 | break;
|
445 | }
|
446 |
|
447 | throw _context7.t1;
|
448 |
|
449 | case 14:
|
450 | case "end":
|
451 | return _context7.stop();
|
452 | }
|
453 | }
|
454 | }, _loop, null, [[3, 10]]);
|
455 | });
|
456 | i = 0;
|
457 |
|
458 | case 2:
|
459 | if (!(i < 5)) {
|
460 | _context8.next = 10;
|
461 | break;
|
462 | }
|
463 |
|
464 | return _context8.delegateYield(_loop(i), "t0", 4);
|
465 |
|
466 | case 4:
|
467 | _ret = _context8.t0;
|
468 |
|
469 | if (!(_typeof(_ret) === "object")) {
|
470 | _context8.next = 7;
|
471 | break;
|
472 | }
|
473 |
|
474 | return _context8.abrupt("return", _ret.v);
|
475 |
|
476 | case 7:
|
477 | i++;
|
478 | _context8.next = 2;
|
479 | break;
|
480 |
|
481 | case 10:
|
482 | case "end":
|
483 | return _context8.stop();
|
484 | }
|
485 | }
|
486 | }, _callee7);
|
487 | }));
|
488 |
|
489 | function connect(_x8, _x9, _x10) {
|
490 | return _connect.apply(this, arguments);
|
491 | }
|
492 |
|
493 | return connect;
|
494 | }()
|
495 | }, {
|
496 | key: "_connectIn",
|
497 | value: function () {
|
498 | var _connectIn2 = _asyncToGenerator(
|
499 |
|
500 | _regenerator["default"].mark(function _callee8(path, debug, first) {
|
501 | var device, chromeOS, interfaceId;
|
502 | return _regenerator["default"].wrap(function _callee8$(_context9) {
|
503 | while (1) {
|
504 | switch (_context9.prev = _context9.next) {
|
505 | case 0:
|
506 | _context9.next = 2;
|
507 | return this._findDevice(path);
|
508 |
|
509 | case 2:
|
510 | device = _context9.sent;
|
511 | _context9.next = 5;
|
512 | return device.open();
|
513 |
|
514 | case 5:
|
515 | if (!first) {
|
516 | _context9.next = 13;
|
517 | break;
|
518 | }
|
519 |
|
520 | _context9.next = 8;
|
521 | return device.selectConfiguration(this.configurationId);
|
522 |
|
523 | case 8:
|
524 | if (!(typeof navigator !== "undefined")) {
|
525 | _context9.next = 13;
|
526 | break;
|
527 | }
|
528 |
|
529 | chromeOS = /\bCrOS\b/.test(navigator.userAgent);
|
530 |
|
531 | if (chromeOS) {
|
532 | _context9.next = 13;
|
533 | break;
|
534 | }
|
535 |
|
536 | _context9.next = 13;
|
537 | return device.reset();
|
538 |
|
539 | case 13:
|
540 | interfaceId = debug ? this.debugInterfaceId : this.normalInterfaceId;
|
541 | _context9.next = 16;
|
542 | return device.claimInterface(interfaceId);
|
543 |
|
544 | case 16:
|
545 | case "end":
|
546 | return _context9.stop();
|
547 | }
|
548 | }
|
549 | }, _callee8, this);
|
550 | }));
|
551 |
|
552 | function _connectIn(_x11, _x12, _x13) {
|
553 | return _connectIn2.apply(this, arguments);
|
554 | }
|
555 |
|
556 | return _connectIn;
|
557 | }()
|
558 | }, {
|
559 | key: "disconnect",
|
560 | value: function () {
|
561 | var _disconnect = _asyncToGenerator(
|
562 |
|
563 | _regenerator["default"].mark(function _callee9(path, debug, last) {
|
564 | var device, interfaceId;
|
565 | return _regenerator["default"].wrap(function _callee9$(_context10) {
|
566 | while (1) {
|
567 | switch (_context10.prev = _context10.next) {
|
568 | case 0:
|
569 | _context10.next = 2;
|
570 | return this._findDevice(path);
|
571 |
|
572 | case 2:
|
573 | device = _context10.sent;
|
574 | interfaceId = debug ? this.debugInterfaceId : this.normalInterfaceId;
|
575 | _context10.next = 6;
|
576 | return device.releaseInterface(interfaceId);
|
577 |
|
578 | case 6:
|
579 | if (!last) {
|
580 | _context10.next = 9;
|
581 | break;
|
582 | }
|
583 |
|
584 | _context10.next = 9;
|
585 | return device.close();
|
586 |
|
587 | case 9:
|
588 | case "end":
|
589 | return _context10.stop();
|
590 | }
|
591 | }
|
592 | }, _callee9, this);
|
593 | }));
|
594 |
|
595 | function disconnect(_x14, _x15, _x16) {
|
596 | return _disconnect.apply(this, arguments);
|
597 | }
|
598 |
|
599 | return disconnect;
|
600 | }()
|
601 | }, {
|
602 | key: "requestDevice",
|
603 | value: function () {
|
604 | var _requestDevice = _asyncToGenerator(
|
605 |
|
606 | _regenerator["default"].mark(function _callee10() {
|
607 | return _regenerator["default"].wrap(function _callee10$(_context11) {
|
608 | while (1) {
|
609 | switch (_context11.prev = _context11.next) {
|
610 | case 0:
|
611 | _context11.next = 2;
|
612 | return this.usb.requestDevice({
|
613 | filters: TREZOR_DESCS
|
614 | });
|
615 |
|
616 | case 2:
|
617 | case "end":
|
618 | return _context11.stop();
|
619 | }
|
620 | }
|
621 | }, _callee10, this);
|
622 | }));
|
623 |
|
624 | function requestDevice() {
|
625 | return _requestDevice.apply(this, arguments);
|
626 | }
|
627 |
|
628 | return requestDevice;
|
629 | }()
|
630 | }]);
|
631 |
|
632 | return WebUsbPlugin;
|
633 | }(), _temp), (_applyDecoratedDescriptor(_class.prototype, "init", [_debugDecorator.debugInOut], Object.getOwnPropertyDescriptor(_class.prototype, "init"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "connect", [_debugDecorator.debugInOut], Object.getOwnPropertyDescriptor(_class.prototype, "connect"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "disconnect", [_debugDecorator.debugInOut], Object.getOwnPropertyDescriptor(_class.prototype, "disconnect"), _class.prototype)), _class);
|
634 | exports["default"] = WebUsbPlugin;
|
635 | module.exports = exports.default; |
\ | No newline at end of file |