diff --git a/package.json b/package.json index 9ee3d020..9c98dca4 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@ledgerhq/hw-transport": "^4.32.0", "@ledgerhq/hw-transport-node-hid": "^4.32.0", "@ledgerhq/ledger-core": "2.0.0-rc.14", - "@ledgerhq/live-common": "4.8.0-beta.4", + "@ledgerhq/live-common": "4.8.0-beta.12", "animated": "^0.2.2", "async": "^2.6.1", "axios": "^0.18.0", diff --git a/src/commands/.DS_Store b/src/commands/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/src/commands/.DS_Store differ diff --git a/src/commands/firmwareCheckId.js b/src/commands/firmwareCheckId.js new file mode 100644 index 00000000..17025469 --- /dev/null +++ b/src/commands/firmwareCheckId.js @@ -0,0 +1,19 @@ +// @flow + +import checkId from '@ledgerhq/live-common/lib/hw/firmwareUpdate-checkId' +import type { OsuFirmware } from '@ledgerhq/live-common/lib/types/manager' +import { createCommand, Command } from 'helpers/ipc' + +type Input = { + devicePath: string, + osuFirmware: OsuFirmware, +} + +type Result = * + +const cmd: Command = createCommand( + 'firmwareCheckId', + ({ devicePath, osuFirmware }) => checkId(devicePath, osuFirmware), +) + +export default cmd diff --git a/src/commands/firmwareMain.js b/src/commands/firmwareMain.js new file mode 100644 index 00000000..4397a590 --- /dev/null +++ b/src/commands/firmwareMain.js @@ -0,0 +1,19 @@ +// @flow + +import main from '@ledgerhq/live-common/lib/hw/firmwareUpdate-main' +import type { FinalFirmware } from '@ledgerhq/live-common/lib/types/manager' +import { createCommand, Command } from 'helpers/ipc' + +type Input = { + finalFirmware: FinalFirmware, +} + +type Result = * + +const cmd: Command = createCommand( + 'firmwareMain', + ({ finalFirmware }) => main('', finalFirmware), + // devicePath='' HACK to not depend on a devicePath because it's dynamic +) + +export default cmd diff --git a/src/commands/firmwareRepair.js b/src/commands/firmwareRepair.js new file mode 100644 index 00000000..41e34401 --- /dev/null +++ b/src/commands/firmwareRepair.js @@ -0,0 +1,14 @@ +// @flow + +import repair from '@ledgerhq/live-common/lib/hw/firmwareUpdate-repair' +import { createCommand, Command } from 'helpers/ipc' + +type Input = void +type Result = * + +const cmd: Command = createCommand( + 'firmwareRepair', + () => repair(''), // devicePath='' HACK to not depend on a devicePath because it's dynamic +) + +export default cmd diff --git a/src/commands/getLatestFirmwareForDevice.js b/src/commands/getLatestFirmwareForDevice.js index e88f6a50..5dfe8a72 100644 --- a/src/commands/getLatestFirmwareForDevice.js +++ b/src/commands/getLatestFirmwareForDevice.js @@ -1,15 +1,18 @@ // @flow import { createCommand, Command } from 'helpers/ipc' -import { fromPromise } from 'rxjs/observable/fromPromise' -import type { DeviceInfo, OsuFirmware } from 'helpers/types' +import { from } from 'rxjs' +import type { + DeviceInfo, + OsuFirmware, + FinalFirmware, +} from '@ledgerhq/live-common/lib/types/manager' +import manager from '@ledgerhq/live-common/lib/manager' -import getLatestFirmwareForDevice from '../helpers/devices/getLatestFirmwareForDevice' +type Result = ?{ osu: OsuFirmware, final: FinalFirmware } -type Result = ?(OsuFirmware & { shouldFlashMcu: boolean }) - -const cmd: Command = createCommand('getLatestFirmwareForDevice', data => - fromPromise(getLatestFirmwareForDevice(data)), +const cmd: Command = createCommand('getLatestFirmwareForDevice', deviceInfo => + from(manager.getLatestFirmwareForDevice(deviceInfo)), ) export default cmd diff --git a/src/commands/index.js b/src/commands/index.js index 1022021c..a55d2bb4 100644 --- a/src/commands/index.js +++ b/src/commands/index.js @@ -4,6 +4,9 @@ import invariant from 'invariant' import type { Command } from 'helpers/ipc' import debugAppInfosForCurrency from 'commands/debugAppInfosForCurrency' +import firmwareCheckId from 'commands/firmwareCheckId' +import firmwareMain from 'commands/firmwareMain' +import firmwareRepair from 'commands/firmwareRepair' import getAddress from 'commands/getAddress' import getDeviceInfo from 'commands/getDeviceInfo' import getCurrentFirmware from 'commands/getCurrentFirmware' @@ -11,9 +14,6 @@ import getIsGenuine from 'commands/getIsGenuine' import getLatestFirmwareForDevice from 'commands/getLatestFirmwareForDevice' import getMemInfo from 'commands/getMemInfo' import installApp from 'commands/installApp' -import installFinalFirmware from 'commands/installFinalFirmware' -import installMcu from 'commands/installMcu' -import installOsuFirmware from 'commands/installOsuFirmware' import isDashboardOpen from 'commands/isDashboardOpen' import killInternalProcess from 'commands/killInternalProcess' import libcoreGetFees from 'commands/libcoreGetFees' @@ -28,7 +28,6 @@ import listAppVersions from 'commands/listAppVersions' import listCategories from 'commands/listCategories' import listenDevices from 'commands/listenDevices' import ping from 'commands/ping' -import shouldFlashMcu from 'commands/shouldFlashMcu' import signTransaction from 'commands/signTransaction' import testApdu from 'commands/testApdu' import testCrash from 'commands/testCrash' @@ -37,6 +36,9 @@ import uninstallApp from 'commands/uninstallApp' const all: Array> = [ debugAppInfosForCurrency, + firmwareCheckId, + firmwareMain, + firmwareRepair, getAddress, getDeviceInfo, getCurrentFirmware, @@ -44,9 +46,6 @@ const all: Array> = [ getLatestFirmwareForDevice, getMemInfo, installApp, - installFinalFirmware, - installMcu, - installOsuFirmware, isDashboardOpen, killInternalProcess, libcoreGetFees, @@ -61,7 +60,6 @@ const all: Array> = [ listCategories, listenDevices, ping, - shouldFlashMcu, signTransaction, testApdu, testCrash, diff --git a/src/commands/installApp.js b/src/commands/installApp.js index 2fd3c1c4..71e04ecb 100644 --- a/src/commands/installApp.js +++ b/src/commands/installApp.js @@ -1,25 +1,21 @@ // @flow import { createCommand, Command } from 'helpers/ipc' -import { from } from 'rxjs' +import installApp from '@ledgerhq/live-common/lib/hw/installApp' import { withDevice } from '@ledgerhq/live-common/lib/hw/deviceAccess' -import installApp from 'helpers/apps/installApp' - -import type { ApplicationVersion } from 'helpers/types' +import type { ApplicationVersion } from '@ledgerhq/live-common/lib/types/manager' type Input = { - app: ApplicationVersion, devicePath: string, targetId: string | number, + app: ApplicationVersion, } -type Result = void +type Result = * -const cmd: Command = createCommand( - 'installApp', - ({ devicePath, targetId, ...app }) => - withDevice(devicePath)(transport => from(installApp(transport, targetId, app))), +const cmd: Command = createCommand('installApp', ({ devicePath, targetId, app }) => + withDevice(devicePath)(transport => installApp(transport, targetId, app)), ) export default cmd diff --git a/src/commands/installFinalFirmware.js b/src/commands/installFinalFirmware.js deleted file mode 100644 index bf56eeb3..00000000 --- a/src/commands/installFinalFirmware.js +++ /dev/null @@ -1,21 +0,0 @@ -// @flow - -import { createCommand, Command } from 'helpers/ipc' -import { from } from 'rxjs' -import { withDevice } from '@ledgerhq/live-common/lib/hw/deviceAccess' - -import installFinalFirmware from 'helpers/firmware/installFinalFirmware' - -type Input = { - devicePath: string, -} - -type Result = { - success: boolean, -} - -const cmd: Command = createCommand('installFinalFirmware', ({ devicePath }) => - withDevice(devicePath)(transport => from(installFinalFirmware(transport))), -) - -export default cmd diff --git a/src/commands/installMcu.js b/src/commands/installMcu.js deleted file mode 100644 index 1301a68b..00000000 --- a/src/commands/installMcu.js +++ /dev/null @@ -1,19 +0,0 @@ -// @flow - -import { createCommand, Command } from 'helpers/ipc' -import { from } from 'rxjs' - -import { withDevice } from '@ledgerhq/live-common/lib/hw/deviceAccess' -import installMcu from 'helpers/firmware/installMcu' - -type Input = { - devicePath: string, -} - -type Result = void - -const cmd: Command = createCommand('installMcu', ({ devicePath }) => - withDevice(devicePath)(transport => from(installMcu(transport))), -) - -export default cmd diff --git a/src/commands/installOsuFirmware.js b/src/commands/installOsuFirmware.js deleted file mode 100644 index e306eaa4..00000000 --- a/src/commands/installOsuFirmware.js +++ /dev/null @@ -1,25 +0,0 @@ -// @flow - -import { createCommand, Command } from 'helpers/ipc' -import { from } from 'rxjs' - -import { withDevice } from '@ledgerhq/live-common/lib/hw/deviceAccess' -import installOsuFirmware from 'helpers/firmware/installOsuFirmware' - -import type { Firmware } from 'components/modals/UpdateFirmware' - -type Input = { - devicePath: string, - targetId: string | number, - firmware: Firmware, -} - -type Result = { success: boolean } - -const cmd: Command = createCommand( - 'installOsuFirmware', - ({ devicePath, firmware, targetId }) => - withDevice(devicePath)(transport => from(installOsuFirmware(transport, targetId, firmware))), -) - -export default cmd diff --git a/src/commands/shouldFlashMcu.js b/src/commands/shouldFlashMcu.js deleted file mode 100644 index f58c629c..00000000 --- a/src/commands/shouldFlashMcu.js +++ /dev/null @@ -1,15 +0,0 @@ -// @flow - -import { createCommand, Command } from 'helpers/ipc' -import { fromPromise } from 'rxjs/observable/fromPromise' -import shouldFlashMcu from 'helpers/devices/shouldFlashMcu' - -import type { DeviceInfo } from 'helpers/types' - -type Result = boolean - -const cmd: Command = createCommand('shouldFlashMcu', data => - fromPromise(shouldFlashMcu(data)), -) - -export default cmd diff --git a/src/commands/uninstallApp.js b/src/commands/uninstallApp.js index b0b581b8..684712c3 100644 --- a/src/commands/uninstallApp.js +++ b/src/commands/uninstallApp.js @@ -1,10 +1,8 @@ // @flow import { createCommand, Command } from 'helpers/ipc' -import { from } from 'rxjs' import { withDevice } from '@ledgerhq/live-common/lib/hw/deviceAccess' - -import uninstallApp from 'helpers/apps/uninstallApp' +import uninstallApp from '@ledgerhq/live-common/lib/hw/uninstallApp' import type { ApplicationVersion } from 'helpers/types' @@ -14,12 +12,10 @@ type Input = { targetId: string | number, } -type Result = void +type Result = * -const cmd: Command = createCommand( - 'uninstallApp', - ({ devicePath, targetId, ...app }) => - withDevice(devicePath)(transport => from(uninstallApp(transport, targetId, app))), +const cmd: Command = createCommand('uninstallApp', ({ devicePath, targetId, app }) => + withDevice(devicePath)(transport => uninstallApp(transport, targetId, app)), ) export default cmd diff --git a/src/components/GenuineCheck.js b/src/components/GenuineCheck.js index ff02986c..76a53ba7 100644 --- a/src/components/GenuineCheck.js +++ b/src/components/GenuineCheck.js @@ -18,6 +18,7 @@ import { CantOpenDevice, DeviceNotGenuineError, DeviceGenuineSocketEarlyClose, + UnexpectedBootloader, } from '@ledgerhq/live-common/lib/errors' import getDeviceInfo from 'commands/getDeviceInfo' @@ -81,7 +82,12 @@ class GenuineCheck extends PureComponent { device: Device, deviceInfo: DeviceInfo, }) => { - if (deviceInfo.isOSU || deviceInfo.isBootloader) { + if (deviceInfo.isBootloader) { + logger.log('device is in bootloader mode') + throw new UnexpectedBootloader() + } + + if (deviceInfo.isOSU) { logger.log('device is in update mode. skipping genuine') return true } diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js index 91443678..a155af7c 100644 --- a/src/components/ManagerPage/AppsList.js +++ b/src/components/ManagerPage/AppsList.js @@ -6,6 +6,8 @@ import styled from 'styled-components' import { translate } from 'react-i18next' import { connect } from 'react-redux' import { compose } from 'redux' +import { throttleTime, filter, map } from 'rxjs/operators' + import type { Device, T } from 'types/common' import type { ApplicationVersion, DeviceInfo } from 'helpers/types' import { getFullListSortedCryptoCurrencies } from 'helpers/countervalues' @@ -19,7 +21,7 @@ import Space from 'components/base/Space' import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal' import Tooltip from 'components/base/Tooltip' import Text from 'components/base/Text' -import Progress from 'components/base/Progress' +import ProgressBar from 'components/ProgressBar' import Spinner from 'components/base/Spinner' import Button from 'components/base/Button' import TranslatedError from 'components/TranslatedError' @@ -65,6 +67,7 @@ type State = { appsLoaded: boolean, app: string, mode: Mode, + progress: number, } const oldAppsInstallDisabled = ['ZenCash', 'Ripple'] @@ -86,6 +89,7 @@ class AppsList extends PureComponent { appsLoaded: false, app: '', mode: 'home', + progress: 0, } componentDidMount() { @@ -158,41 +162,44 @@ class AppsList extends PureComponent { } } - handleInstallApp = (app: ApplicationVersion) => async () => { - this.setState({ status: 'busy', app: app.name, mode: 'installing' }) - try { - const { - device: { path: devicePath }, - deviceInfo, - } = this.props - const data = { app, devicePath, targetId: deviceInfo.targetId } - await installApp.send(data).toPromise() - this.setState({ status: 'success' }) - } catch (err) { - this.setState({ status: 'error', error: err, mode: 'home' }) - } + sub: * + runAppScript = (app: ApplicationVersion, mode: *, cmd: *) => { + this.setState({ status: 'busy', app: app.name, mode, progress: 0 }) + const { + device: { path: devicePath }, + deviceInfo: { targetId }, + } = this.props + this.sub = cmd + .send({ app, devicePath, targetId }) + .pipe( + filter(e => e.type === 'bulk-progress'), // only bulk progress interests the UI + throttleTime(100), // throttle to only emit 10 event/s max, to not spam the UI + map(e => e.progress), // extract a stream of progress percentage + ) + .subscribe({ + next: progress => { + this.setState({ progress }) + }, + complete: () => { + this.setState({ status: 'success' }) + }, + error: error => { + this.setState({ status: 'error', error, app: '', mode: 'home' }) + }, + }) } - handleUninstallApp = (app: ApplicationVersion) => async () => { - this.setState({ status: 'busy', app: app.name, mode: 'uninstalling' }) - try { - const { - device: { path: devicePath }, - deviceInfo, - } = this.props - const data = { app, devicePath, targetId: deviceInfo.targetId } - await uninstallApp.send(data).toPromise() - this.setState({ status: 'success' }) - } catch (err) { - this.setState({ status: 'error', error: err, app: '', mode: 'home' }) - } - } + handleInstallApp = (app: ApplicationVersion) => () => + this.runAppScript(app, 'installing', installApp) + + handleUninstallApp = (app: ApplicationVersion) => () => + this.runAppScript(app, 'uninstalling', uninstallApp) handleCloseModal = () => this.setState({ status: 'idle', mode: 'home' }) renderModal = () => { const { t } = this.props - const { app, status, error, mode } = this.state + const { app, status, error, mode, progress } = this.state return ( { {t(`manager.apps.${mode}`, { app })} - + diff --git a/src/components/ManagerPage/FirmwareUpdate.js b/src/components/ManagerPage/FirmwareUpdate.js index 90e997b1..e9c7fe72 100644 --- a/src/components/ManagerPage/FirmwareUpdate.js +++ b/src/components/ManagerPage/FirmwareUpdate.js @@ -5,18 +5,17 @@ import React, { PureComponent, Fragment } from 'react' import { translate } from 'react-i18next' import isEqual from 'lodash/isEqual' import isEmpty from 'lodash/isEmpty' -import invariant from 'invariant' import type { Device, T } from 'types/common' -import type { DeviceInfo, OsuFirmware } from 'helpers/types' +import type { + DeviceInfo, + OsuFirmware, + FinalFirmware, +} from '@ledgerhq/live-common/lib/types/manager' import type { StepId } from 'components/modals/UpdateFirmware' import getLatestFirmwareForDevice from 'commands/getLatestFirmwareForDevice' -import shouldFlashMcu from 'commands/shouldFlashMcu' -import installOsuFirmware from 'commands/installOsuFirmware' -import installFinalFirmware from 'commands/installFinalFirmware' -import installMcu from 'commands/installMcu' import DisclaimerModal from 'components/modals/UpdateFirmware/Disclaimer' import UpdateModal from 'components/modals/UpdateFirmware' @@ -42,7 +41,7 @@ type Props = { } type State = { - latestFirmware: ?OsuFirmware & ?{ shouldFlashMcu: boolean }, + firmware: ?{ osu: OsuFirmware, final: FinalFirmware }, modal: ModalStatus, stepId: ?StepId, shouldFlash: boolean, @@ -50,7 +49,7 @@ type State = { } const intializeState = ({ deviceInfo }): State => ({ - latestFirmware: null, + firmware: null, modal: 'closed', stepId: deviceInfo.isBootloader ? 'updateMCU' : 'idCheck', shouldFlash: false, @@ -64,9 +63,7 @@ class FirmwareUpdate extends PureComponent { const { deviceInfo } = this.props if (!deviceInfo.isOSU && !deviceInfo.isBootloader) { this.fetchLatestFirmware() - } else if (deviceInfo.isOSU) { - this.shouldFlashMcu() - } else if (deviceInfo.isBootloader) { + } else { this.handleInstallModal('updateMCU', true) } } @@ -79,45 +76,16 @@ class FirmwareUpdate extends PureComponent { fetchLatestFirmware = async () => { const { deviceInfo } = this.props - const latestFirmware = await getLatestFirmwareForDevice.send(deviceInfo).toPromise() - if ( - !isEmpty(latestFirmware) && - !isEqual(this.state.latestFirmware, latestFirmware) && - !this._unmounting - ) { - this.setState({ latestFirmware, ready: true }) + const firmware = await getLatestFirmwareForDevice.send(deviceInfo).toPromise() + if (!isEmpty(firmware) && !isEqual(this.state.firmware, firmware) && !this._unmounting) { + this.setState({ firmware, ready: true }) } } - shouldFlashMcu = async () => { - const { deviceInfo } = this.props - const shouldFlash = await shouldFlashMcu.send(deviceInfo).toPromise() - if (!this._unmounting) { - this.setState({ shouldFlash, modal: 'install', stepId: 'idCheck', ready: true }) - } - } - - installOsuFirmware = async (device: Device) => { - const { latestFirmware } = this.state - const { deviceInfo } = this.props - invariant(latestFirmware, 'did not find a new firmware or firmware is not set') - - this.setState({ modal: 'install' }) - const result = await installOsuFirmware - .send({ devicePath: device.path, firmware: latestFirmware, targetId: deviceInfo.targetId }) - .toPromise() - - return result - } - - installFinalFirmware = (device: Device) => - installFinalFirmware.send({ devicePath: device.path }).toPromise() - - flashMCU = async (device: Device) => installMcu.send({ devicePath: device.path }).toPromise() - handleCloseModal = () => this.setState({ modal: 'closed' }) handleDisclaimerModal = () => this.setState({ modal: 'disclaimer' }) + handleInstallModal = (stepId: StepId = 'idCheck', shouldFlash?: boolean) => this.setState({ modal: 'install', stepId, shouldFlash, ready: true }) @@ -125,7 +93,7 @@ class FirmwareUpdate extends PureComponent { render() { const { deviceInfo, t, device } = this.props - const { latestFirmware, modal, stepId, shouldFlash, ready } = this.state + const { firmware, modal, stepId, shouldFlash, ready } = this.state return ( @@ -151,12 +119,12 @@ class FirmwareUpdate extends PureComponent { })} - + {ready ? ( { status={modal} stepId={stepId} onClose={this.handleCloseModal} - firmware={latestFirmware} + firmware={firmware} shouldFlashMcu={shouldFlash} - installOsuFirmware={this.installOsuFirmware} - installFinalFirmware={this.installFinalFirmware} - flashMCU={this.flashMCU} /> ) : null} diff --git a/src/components/ManagerPage/UpdateFirmwareButton.js b/src/components/ManagerPage/UpdateFirmwareButton.js index fcfc529e..66d6e314 100644 --- a/src/components/ManagerPage/UpdateFirmwareButton.js +++ b/src/components/ManagerPage/UpdateFirmwareButton.js @@ -3,19 +3,14 @@ import React, { Fragment } from 'react' import { translate } from 'react-i18next' import type { T } from 'types/common' - +import type { OsuFirmware, FinalFirmware } from '@ledgerhq/live-common/lib/types/manager' import Button from 'components/base/Button' import Text from 'components/base/Text' import { getCleanVersion } from 'components/ManagerPage/FirmwareUpdate' -type FirmwareInfos = { - name: string, - notes: string, -} - type Props = { t: T, - firmware: ?FirmwareInfos, + firmware: ?{ osu: OsuFirmware, finalFirmware: FinalFirmware }, onClick: () => void, } @@ -23,14 +18,14 @@ const UpdateFirmwareButton = ({ t, firmware, onClick }: Props) => firmware ? ( - {t('manager.firmware.latest', { version: getCleanVersion(firmware.name) })} + {t('manager.firmware.latest', { version: getCleanVersion(firmware.osu.name) })} + + + + ) + } +} + +export default translate()(CleanButton) diff --git a/src/components/SettingsPage/sections/Help.js b/src/components/SettingsPage/sections/Help.js index c4577020..15eba3c4 100644 --- a/src/components/SettingsPage/sections/Help.js +++ b/src/components/SettingsPage/sections/Help.js @@ -11,6 +11,7 @@ import ExportLogsBtn from 'components/ExportLogsBtn' import OpenUserDataDirectoryBtn from 'components/OpenUserDataDirectoryBtn' import CleanButton from '../CleanButton' import ResetButton from '../ResetButton' +import RepairDeviceButton from '../RepairDeviceButton' import AboutRowItem from '../AboutRowItem' import LaunchOnboardingBtn from '../LaunchOnboardingBtn' @@ -72,6 +73,12 @@ class SectionHelp extends PureComponent { > + + + ) diff --git a/src/components/base/Modal/ConfirmModal.js b/src/components/base/Modal/ConfirmModal.js index 9ed7cbe6..0512a981 100644 --- a/src/components/base/Modal/ConfirmModal.js +++ b/src/components/base/Modal/ConfirmModal.js @@ -25,11 +25,13 @@ type Props = { t: T, isLoading?: boolean, analyticsName: string, + cancellable?: boolean, } class ConfirmModal extends PureComponent { render() { const { + cancellable, isOpened, title, subTitle, @@ -54,7 +56,7 @@ class ConfirmModal extends PureComponent { preventBackdropClick={isLoading} {...props} render={({ onClose }) => ( - + {title} diff --git a/src/components/modals/UpdateFirmware/Disclaimer.js b/src/components/modals/UpdateFirmware/Disclaimer.js index f4fce175..bdc9d22f 100644 --- a/src/components/modals/UpdateFirmware/Disclaimer.js +++ b/src/components/modals/UpdateFirmware/Disclaimer.js @@ -3,7 +3,7 @@ import React, { PureComponent, Fragment } from 'react' import { translate, Trans } from 'react-i18next' - +import type { OsuFirmware, FinalFirmware } from '@ledgerhq/live-common/lib/types/manager' import type { T } from 'types/common' import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal' @@ -18,15 +18,13 @@ import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate' import { getCleanVersion } from 'components/ManagerPage/FirmwareUpdate' -type FirmwareInfos = { - name: string, - notes: string, -} - type Props = { t: T, status: ModalStatus, - firmware: FirmwareInfos, + firmware: { + osu: OsuFirmware, + final: FinalFirmware, + }, goToNextStep: () => void, onClose: () => void, } @@ -50,7 +48,7 @@ class DisclaimerModal extends PureComponent { You are about to install - {`firmware version ${firmware ? getCleanVersion(firmware.name) : ''}`} + {`firmware version ${firmware ? getCleanVersion(firmware.osu.name) : ''}`} @@ -62,7 +60,7 @@ class DisclaimerModal extends PureComponent { - {firmware.notes} + {firmware.osu.notes} diff --git a/src/components/modals/UpdateFirmware/Installing.js b/src/components/modals/UpdateFirmware/Installing.js index 2333399e..5a06c152 100644 --- a/src/components/modals/UpdateFirmware/Installing.js +++ b/src/components/modals/UpdateFirmware/Installing.js @@ -4,19 +4,20 @@ import { translate } from 'react-i18next' import Box from 'components/base/Box' import Text from 'components/base/Text' -import Spinner from 'components/base/Spinner' +import ProgressCircle from 'components/ProgressCircle' import type { T } from 'types/common' type Props = { t: T, + progress: number, } -function Installing({ t }: Props) { +function Installing({ t, progress }: Props) { return ( - + diff --git a/src/components/modals/UpdateFirmware/index.js b/src/components/modals/UpdateFirmware/index.js index d2888743..a18a8023 100644 --- a/src/components/modals/UpdateFirmware/index.js +++ b/src/components/modals/UpdateFirmware/index.js @@ -2,22 +2,22 @@ import React, { PureComponent } from 'react' import { translate } from 'react-i18next' -import type { T, Device } from 'types/common' +import type { T } from 'types/common' import Modal from 'components/base/Modal' import Stepper from 'components/base/Stepper' import SyncSkipUnderPriority from 'components/SyncSkipUnderPriority' +import type { OsuFirmware, FinalFirmware } from '@ledgerhq/live-common/lib/types/manager' import type { StepProps as DefaultStepProps, Step } from 'components/base/Stepper' import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate' -import type { OsuFirmware } from 'helpers/types' import { FreezeDeviceChangeEvents } from '../../ManagerPage/HookDeviceChange' import StepFullFirmwareInstall from './steps/01-step-install-full-firmware' import StepFlashMcu from './steps/02-step-flash-mcu' import StepConfirmation, { StepConfirmFooter } from './steps/03-step-confirmation' -const createSteps = ({ t, shouldFlashMcu }: { t: T, shouldFlashMcu: boolean }): Array<*> => { +const createSteps = ({ t }: { t: T }): Array<*> => { const updateStep = { id: 'idCheck', label: t('manager.modal.identifier'), @@ -45,26 +45,13 @@ const createSteps = ({ t, shouldFlashMcu }: { t: T, shouldFlashMcu: boolean }): hideFooter: true, } - const steps = [updateStep] - - if (shouldFlashMcu) { - steps.push(mcuStep) - } - - steps.push(finalStep) - - return steps + return [updateStep, mcuStep, finalStep] } -export type Firmware = OsuFirmware & { shouldFlashMcu: boolean } - export type StepProps = DefaultStepProps & { - firmware: Firmware, + osu: OsuFirmware, + final: FinalFirmware, onCloseModal: () => void, - installOsuFirmware: (device: Device) => void, - installFinalFirmware: (device: Device) => void, - flashMCU: (device: Device) => void, - shouldFlashMcu: boolean, error: ?Error, setError: Error => void, } @@ -75,11 +62,7 @@ type Props = { t: T, status: ModalStatus, onClose: () => void, - firmware: Firmware, - shouldFlashMcu: boolean, - installOsuFirmware: (device: Device) => void, - installFinalFirmware: (device: Device) => void, - flashMCU: (device: Device) => void, + firmware: { osu: OsuFirmware, final: FinalFirmware }, stepId: StepId | string, } @@ -98,9 +81,6 @@ class UpdateModal extends PureComponent { STEPS = createSteps({ t: this.props.t, - shouldFlashMcu: this.props.firmware - ? this.props.firmware.shouldFlashMcu - : this.props.shouldFlashMcu, }) setError = (e: Error) => this.setState({ error: e }) @@ -114,10 +94,10 @@ class UpdateModal extends PureComponent { const { stepId, error, nonce } = this.state const additionalProps = { - firmware, error, onCloseModal: onClose, setError: this.setError, + ...firmware, ...props, } diff --git a/src/components/modals/UpdateFirmware/steps/01-step-install-full-firmware.js b/src/components/modals/UpdateFirmware/steps/01-step-install-full-firmware.js index 154eafb0..4121ff06 100644 --- a/src/components/modals/UpdateFirmware/steps/01-step-install-full-firmware.js +++ b/src/components/modals/UpdateFirmware/steps/01-step-install-full-firmware.js @@ -3,24 +3,16 @@ import React, { PureComponent, Fragment } from 'react' import styled from 'styled-components' import { connect } from 'react-redux' -import { timeout } from 'rxjs/operators/timeout' - -import { DEVICE_INFOS_TIMEOUT } from 'config/constants' -import getDeviceInfo from 'commands/getDeviceInfo' +import firmwareCheckId from 'commands/firmwareCheckId' import { getCurrentDevice } from 'reducers/devices' -import { createCancelablePolling, delay } from 'helpers/promise' - import TrackPage from 'analytics/TrackPage' import Box from 'components/base/Box' import Text from 'components/base/Text' import DeviceConfirm from 'components/DeviceConfirm' - import type { Device } from 'types/common' import type { StepProps } from '../' -import Installing from '../Installing' - const Container = styled(Box).attrs({ alignItems: 'center', fontSize: 4, @@ -55,79 +47,37 @@ type Props = StepProps & { device: Device, } -type State = { - installing: boolean, -} - -class StepFullFirmwareInstall extends PureComponent { - state = { - installing: false, - } - +class StepFullFirmwareInstall extends PureComponent { componentDidMount() { - this.install() - } - - componentWillUnmount() { - if (this._unsubConnect) this._unsubConnect() - } + const { osu, device, transitionTo, setError } = this.props - ensureDevice = () => { - const { unsubscribe, promise } = createCancelablePolling(async () => { - const { device } = this.props - if (!device) { - throw new Error('No device') - } - - const deviceInfo = await getDeviceInfo - .send({ devicePath: device.path }) - .pipe(timeout(DEVICE_INFOS_TIMEOUT)) - .toPromise() - return { device, deviceInfo } - }) - this._unsubConnect = unsubscribe - return promise - } - - install = async () => { - const { - installOsuFirmware, - installFinalFirmware, - firmware, - shouldFlashMcu, - transitionTo, - setError, - } = this.props - const { device, deviceInfo } = await this.ensureDevice() - - if (deviceInfo.isBootloader) { - transitionTo('updateMCU') + if (!osu) { + transitionTo('finish') + return } - try { - if (deviceInfo.isOSU) { - this.setState({ installing: true }) - await installFinalFirmware(device) - transitionTo('finish') - } else { - await installOsuFirmware(device) - this.setState({ installing: true }) - if (this._unsubConnect) this._unsubConnect() - if ((firmware && firmware.shouldFlashMcu) || shouldFlashMcu) { - delay(1000) + this.sub = firmwareCheckId + .send({ + devicePath: device.path, + osuFirmware: osu, + }) + .subscribe({ + complete: () => { transitionTo('updateMCU') - } else { - const { device: freshDevice } = await this.ensureDevice() - await installFinalFirmware(freshDevice) + }, + error: error => { + setError(error) transitionTo('finish') - } - } - } catch (error) { - setError(error) - transitionTo('finish') - } + }, + }) } + componentWillUnmount() { + if (this.sub) this.sub.unsubscribe() + } + + sub: * + formatHashName = (hash: string): string => { if (!hash) { return '' @@ -138,11 +88,8 @@ class StepFullFirmwareInstall extends PureComponent { } renderBody = () => { - const { installing } = this.state - const { t, firmware } = this.props - return installing ? ( - - ) : ( + const { t, osu } = this.props + return ( {t('manager.modal.confirmIdentifierText')} @@ -151,7 +98,7 @@ class StepFullFirmwareInstall extends PureComponent { {t('manager.modal.identifier')} -
{firmware && this.formatHashName(firmware.hash)}
+
{osu && this.formatHashName(osu.hash)}
@@ -160,14 +107,11 @@ class StepFullFirmwareInstall extends PureComponent { ) } - _unsubConnect: * - render() { - const { installing } = this.state const { t } = this.props return ( - {installing ? '' : t('manager.modal.confirmIdentifier')} + {t('manager.modal.confirmIdentifier')} {this.renderBody()} diff --git a/src/components/modals/UpdateFirmware/steps/02-step-flash-mcu.js b/src/components/modals/UpdateFirmware/steps/02-step-flash-mcu.js index 2ee8f1a9..308a58b8 100644 --- a/src/components/modals/UpdateFirmware/steps/02-step-flash-mcu.js +++ b/src/components/modals/UpdateFirmware/steps/02-step-flash-mcu.js @@ -2,21 +2,15 @@ import React, { PureComponent, Fragment } from 'react' import styled from 'styled-components' -import { connect } from 'react-redux' -import { timeout } from 'rxjs/operators/timeout' +import { filter, tap } from 'rxjs/operators' -import { DEVICE_INFOS_TIMEOUT } from 'config/constants' import { i } from 'helpers/staticPath' -import { getCurrentDevice } from 'reducers/devices' -import { createCancelablePolling } from 'helpers/promise' -import getDeviceInfo from 'commands/getDeviceInfo' +import firmwareMain from 'commands/firmwareMain' import TrackPage from 'analytics/TrackPage' import Box from 'components/base/Box' import Text from 'components/base/Text' -import type { Device } from 'types/common' - import type { StepProps } from '../' import Installing from '../Installing' @@ -46,107 +40,59 @@ const Separator = styled(Box).attrs({ background-color: currentColor; ` -const mapStateToProps = state => ({ - device: getCurrentDevice(state), -}) - -type Props = StepProps & { device?: Device } +type Props = StepProps type State = { installing: boolean, + progress: number, } class StepFlashMcu extends PureComponent { state = { installing: false, + progress: 0, } componentDidMount() { - this.install() + const { final: finalFirmware, transitionTo, setError } = this.props + + this.sub = firmwareMain + .send({ finalFirmware }) + .pipe( + tap(e => console.log(e)), // eslint-disable-line no-console + // ^ TODO remove at the end + filter(e => e.type === 'bulk-progress' || e.type === 'install'), + ) + .subscribe({ + next: e => { + if (e.type === 'install') { + this.setState({ installing: e.step, progress: 0 }) + } else { + this.setState({ progress: e.progress }) + } + }, + complete: () => { + transitionTo('finish') + }, + error: error => { + setError(error) + transitionTo('finish') + }, + }) } componentWillUnmount() { - if (this._unsubConnect) this._unsubConnect() - if (this._unsubDeviceInfo) this._unsubDeviceInfo() - } - - getDeviceInfo = () => { - const { unsubscribe, promise } = createCancelablePolling(async () => { - const { device } = this.props - if (!device) { - throw new Error('No device') - } - const deviceInfo = await getDeviceInfo - .send({ devicePath: device.path }) - .pipe(timeout(DEVICE_INFOS_TIMEOUT)) - .toPromise() - - return { device, deviceInfo } - }) - this._unsubDeviceInfo = unsubscribe - return promise + if (this.sub) this.sub.unsubscribe() } - waitForDeviceInBootloader = () => { - const { unsubscribe, promise } = createCancelablePolling(async () => { - const { device } = this.props - if (!device) { - throw new Error('No device') - } - const deviceInfo = await getDeviceInfo - .send({ devicePath: device.path }) - .pipe(timeout(DEVICE_INFOS_TIMEOUT)) - .toPromise() - - if (!deviceInfo.isBootloader) { - throw new Error('Device is not in bootloader') - } - return { device, deviceInfo } - }) - this._unsubConnect = unsubscribe - return promise - } - - flash = async () => { - await this.waitForDeviceInBootloader() - const { flashMCU, device } = this.props - if (device) { - this.setState({ installing: true }) - await flashMCU(device) - } - } - - install = async () => { - const { transitionTo, installFinalFirmware, setError } = this.props - const { deviceInfo, device } = await this.getDeviceInfo() - - try { - if (deviceInfo.isBootloader) { - await this.flash() - this.install() - } else if (deviceInfo.isOSU) { - await installFinalFirmware(device) - transitionTo('finish') - } else { - transitionTo('finish') - } - } catch (error) { - setError(error) - transitionTo('finish') - } - } - - firstFlash = async () => { - await this.flash() - this.install() - } + sub: * renderBody = () => { - const { installing } = this.state + const { installing, progress } = this.state const { t } = this.props return installing ? ( - + ) : ( @@ -176,9 +122,6 @@ class StepFlashMcu extends PureComponent { ) } - _unsubConnect: * - _unsubDeviceInfo: * - render() { const { t } = this.props const { installing } = this.state @@ -192,4 +135,4 @@ class StepFlashMcu extends PureComponent { } } -export default connect(mapStateToProps)(StepFlashMcu) +export default StepFlashMcu diff --git a/src/helpers/devices/getDeviceInfo.js b/src/helpers/devices/getDeviceInfo.js index 24b6d7d1..1bfef909 100644 --- a/src/helpers/devices/getDeviceInfo.js +++ b/src/helpers/devices/getDeviceInfo.js @@ -1,42 +1,5 @@ // @flow -import type Transport from '@ledgerhq/hw-transport' +import getDeviceInfo from '@ledgerhq/live-common/lib/hw/getDeviceInfo' -import getFirmwareInfo from 'helpers/firmware/getFirmwareInfo' -import { FORCE_PROVIDER } from 'config/constants' - -import type { DeviceInfo } from 'helpers/types' - -const PROVIDERS = { - '': 1, - das: 2, - club: 3, - shitcoins: 4, - ee: 5, -} - -export default async (transport: Transport<*>): Promise => { - const res = await getFirmwareInfo(transport) - const { seVersion } = res - const { targetId, mcuVersion, flags } = res - const parsedVersion = - seVersion.match(/([0-9]+.[0-9])+(.[0-9]+)?((?!-osu)-([a-z]+))?(-osu)?/) || [] - const isOSU = typeof parsedVersion[5] !== 'undefined' - const providerName = parsedVersion[4] || '' - const providerId = FORCE_PROVIDER || PROVIDERS[providerName] - const isBootloader = targetId === 0x01000001 - const majMin = parsedVersion[1] - const patch = parsedVersion[2] || '.0' - const fullVersion = `${majMin}${patch}${providerName ? `-${providerName}` : ''}` - return { - targetId, - seVersion: majMin + patch, - isOSU, - mcuVersion, - isBootloader, - providerName, - providerId, - flags, - fullVersion, - } -} +export default getDeviceInfo diff --git a/src/helpers/devices/getLatestFirmwareForDevice.js b/src/helpers/devices/getLatestFirmwareForDevice.js deleted file mode 100644 index 80e14af8..00000000 --- a/src/helpers/devices/getLatestFirmwareForDevice.js +++ /dev/null @@ -1,76 +0,0 @@ -// @flow -import network from 'api/network' -import { GET_LATEST_FIRMWARE } from 'helpers/urls' -import type { - DeviceInfo, - DeviceVersion, - FinalFirmware, - OsuFirmware, - McuVersion, -} from 'helpers/types' - -import getFinalFirmwareById from 'helpers/firmware/getFinalFirmwareById' -import getMcus from 'helpers/firmware/getMcus' - -import getCurrentFirmware from './getCurrentFirmware' -import getDeviceVersion from './getDeviceVersion' - -type NetworkResponse = { - data: { - result: string, - se_firmware_osu_version: OsuFirmware, - }, -} - -type Result = ?(OsuFirmware & { shouldFlashMcu: boolean }) - -export default async (deviceInfo: DeviceInfo): Promise => { - // Get device infos from targetId - const deviceVersion: DeviceVersion = await getDeviceVersion( - deviceInfo.targetId, - deviceInfo.providerId, - ) - - // Get firmware infos with firmware name and device version - const seFirmwareVersion: FinalFirmware = await getCurrentFirmware({ - fullVersion: deviceInfo.fullVersion, - deviceId: deviceVersion.id, - provider: deviceInfo.providerId, - }) - - // Fetch next possible firmware - const { data }: NetworkResponse = await network({ - method: 'POST', - url: GET_LATEST_FIRMWARE, - data: { - current_se_firmware_final_version: seFirmwareVersion.id, - device_version: deviceVersion.id, - provider: deviceInfo.providerId, - }, - }) - - if (data.result === 'null') { - return null - } - - const { se_firmware_osu_version } = data - const { next_se_firmware_final_version } = se_firmware_osu_version - const seFirmwareFinalVersion: FinalFirmware = await getFinalFirmwareById( - next_se_firmware_final_version, - ) - - const mcus: Array = await getMcus() - - const currentMcuVersionId: Array = mcus - .filter(mcu => mcu.name === deviceInfo.mcuVersion) - .map(mcu => mcu.id) - - if (!seFirmwareFinalVersion.mcu_versions.includes(...currentMcuVersionId)) { - return { - ...se_firmware_osu_version, - shouldFlashMcu: true, - } - } - - return { ...se_firmware_osu_version, shouldFlashMcu: false } -} diff --git a/src/helpers/devices/shouldFlashMcu.js b/src/helpers/devices/shouldFlashMcu.js deleted file mode 100644 index 1ed0a768..00000000 --- a/src/helpers/devices/shouldFlashMcu.js +++ /dev/null @@ -1,49 +0,0 @@ -// @flow -import network from 'api/network' -import { GET_LATEST_FIRMWARE } from 'helpers/urls' -import type { DeviceInfo } from 'helpers/types' - -import getFinalFirmwareById from 'helpers/firmware/getFinalFirmwareById' -import getMcus from 'helpers/firmware/getMcus' - -import getOsuFirmware from './getOsuFirmware' -import getDeviceVersion from './getDeviceVersion' - -export default async (deviceInfo: DeviceInfo): Promise => { - // Get device infos from targetId - const deviceVersion = await getDeviceVersion(deviceInfo.targetId, deviceInfo.providerId) - - // Get firmware infos with firmware name and device version - const seFirmwareVersion = await getOsuFirmware({ - version: deviceInfo.fullVersion, - deviceId: deviceVersion.id, - provider: deviceInfo.providerId, - }) - - // Fetch next possible firmware - const { data } = await network({ - method: 'POST', - url: GET_LATEST_FIRMWARE, - data: { - current_se_firmware_final_version: seFirmwareVersion.id, - device_version: deviceVersion.id, - provider: deviceInfo.providerId, - }, - }) - - if (data.result === 'null') { - return false - } - - const { se_firmware_osu_version } = data - const { next_se_firmware_final_version } = se_firmware_osu_version - const seFirmwareFinalVersion = await getFinalFirmwareById(next_se_firmware_final_version) - - const mcus = await getMcus() - - const currentMcuVersionId = mcus - .filter(mcu => mcu.name === deviceInfo.mcuVersion) - .map(mcu => mcu.id) - - return !seFirmwareFinalVersion.mcu_versions.includes(...currentMcuVersionId) -} diff --git a/src/helpers/firmware/installFinalFirmware.js b/src/helpers/firmware/installFinalFirmware.js deleted file mode 100644 index 8d643e31..00000000 --- a/src/helpers/firmware/installFinalFirmware.js +++ /dev/null @@ -1,51 +0,0 @@ -// @flow -import type Transport from '@ledgerhq/hw-transport' -import type { DeviceInfo, DeviceVersion, OsuFirmware, FinalFirmware } from 'helpers/types' - -import { WS_INSTALL } from 'helpers/urls' -import { createDeviceSocket } from 'helpers/socket' -import getDeviceVersion from 'helpers/devices/getDeviceVersion' -import getOsuFirmware from 'helpers/devices/getOsuFirmware' -import getDeviceInfo from 'helpers/devices/getDeviceInfo' -import { ManagerDeviceLockedError } from '@ledgerhq/live-common/lib/errors' - -import getFinalFirmwareById from './getFinalFirmwareById' - -function remapSocketError(promise) { - return promise.catch((e: Error) => { - switch (true) { - case e.message.endsWith('6982'): - throw new ManagerDeviceLockedError() - default: - throw e - } - }) -} - -type Result = Promise<{ success: boolean }> - -export default async (transport: Transport<*>): Result => { - try { - const deviceInfo: DeviceInfo = await getDeviceInfo(transport) - const device: DeviceVersion = await getDeviceVersion(deviceInfo.targetId, deviceInfo.providerId) - const firmware: OsuFirmware = await getOsuFirmware({ - deviceId: device.id, - version: deviceInfo.fullVersion, - provider: deviceInfo.providerId, - }) - const { next_se_firmware_final_version } = firmware - const nextFirmware: FinalFirmware = await getFinalFirmwareById(next_se_firmware_final_version) - - const params = { - targetId: deviceInfo.targetId, - ...nextFirmware, - firmwareKey: nextFirmware.firmware_key, - } - - const url = WS_INSTALL(params) - await remapSocketError(createDeviceSocket(transport, url).toPromise()) - return { success: true } - } catch (error) { - throw error - } -} diff --git a/src/helpers/firmware/installMcu.js b/src/helpers/firmware/installMcu.js deleted file mode 100644 index b8ece4a4..00000000 --- a/src/helpers/firmware/installMcu.js +++ /dev/null @@ -1,34 +0,0 @@ -// @flow -import type Transport from '@ledgerhq/hw-transport' - -import { WS_MCU } from 'helpers/urls' -import { createDeviceSocket } from 'helpers/socket' -import getNextMCU from 'helpers/firmware/getNextMCU' -import getDeviceInfo from 'helpers/devices/getDeviceInfo' -import { ManagerDeviceLockedError } from '@ledgerhq/live-common/lib/errors' - -import type { DeviceInfo } from 'helpers/types' - -function remapSocketError(promise) { - return promise.catch((e: Error) => { - switch (true) { - case e.message.endsWith('6982'): - throw new ManagerDeviceLockedError() - default: - throw e - } - }) -} - -type Result = Promise - -export default async (transport: Transport<*>): Result => { - const { seVersion: version, targetId }: DeviceInfo = await getDeviceInfo(transport) - const nextVersion = await getNextMCU(version) - const params = { - targetId, - version: nextVersion.name, - } - const url = WS_MCU(params) - await remapSocketError(createDeviceSocket(transport, url).toPromise()) -} diff --git a/src/helpers/firmware/installOsuFirmware.js b/src/helpers/firmware/installOsuFirmware.js deleted file mode 100644 index a1194d3c..00000000 --- a/src/helpers/firmware/installOsuFirmware.js +++ /dev/null @@ -1,50 +0,0 @@ -// @flow -import type Transport from '@ledgerhq/hw-transport' - -import { WS_INSTALL } from 'helpers/urls' -import { createDeviceSocket } from 'helpers/socket' - -import type { Firmware } from 'components/modals/UpdateFirmware' - -import { - ManagerNotEnoughSpaceError, - ManagerDeviceLockedError, - UserRefusedFirmwareUpdate, -} from '@ledgerhq/live-common/lib/errors' - -function remapError(promise) { - return promise.catch((e: Error) => { - switch (true) { - case e.message.endsWith('6985'): - throw new UserRefusedFirmwareUpdate() - case e.message.endsWith('6982'): - throw new ManagerDeviceLockedError() - case e.message.endsWith('6a84') || e.message.endsWith('6a85'): - throw new ManagerNotEnoughSpaceError() - default: - throw e - } - }) -} - -type Result = Promise<{ success: boolean }> - -export default async ( - transport: Transport<*>, - targetId: string | number, - firmware: Firmware, -): Result => { - try { - const params = { - targetId, - ...firmware, - firmwareKey: firmware.firmware_key, - } - delete params.shouldFlashMcu - const url = WS_INSTALL(params) - await remapError(createDeviceSocket(transport, url).toPromise()) - return { success: true } - } catch (error) { - throw error - } -} diff --git a/src/helpers/live-common-setup-internal-hw.js b/src/helpers/live-common-setup-internal-hw.js index 02250401..e4dc602d 100644 --- a/src/helpers/live-common-setup-internal-hw.js +++ b/src/helpers/live-common-setup-internal-hw.js @@ -40,7 +40,6 @@ setErrorRemapping(e => { registerTransportModule({ id: 'hid', open: async devicePath => { - // $FlowFixMe const t = await retry(() => TransportNodeHid.open(devicePath), { maxRetry: 2 }) t.setDebugMode(logger.apdu) return t diff --git a/src/helpers/live-common-setup.js b/src/helpers/live-common-setup.js index b740c0a0..458cdf39 100644 --- a/src/helpers/live-common-setup.js +++ b/src/helpers/live-common-setup.js @@ -1,8 +1,10 @@ // @flow -import { setNetwork } from '@ledgerhq/live-common/lib/network' +import WebSocket from 'ws' +import { setNetwork, setWebSocketImplementation } from '@ledgerhq/live-common/lib/network' import { setEnv } from '@ledgerhq/live-common/lib/env' import network from 'api/network' import * as constants from 'config/constants' +setWebSocketImplementation(WebSocket) setNetwork(network) setEnv('FORCE_PROVIDER', constants.FORCE_PROVIDER) diff --git a/static/i18n/en/app.json b/static/i18n/en/app.json index dc2bc93c..9a5868d8 100644 --- a/static/i18n/en/app.json +++ b/static/i18n/en/app.json @@ -445,6 +445,11 @@ "desc": "View the user data that is stored on your computer, including your accounts, caches and settings.", "btn": "View" }, + "repairDevice": { + "title": "Repair your Ledger device", + "desc": "If you encountered some issue while updating your device and cannot resume the update process, you can try this option to repair your device.", + "button": "Repair" + }, "exportLogs": { "title": "Export logs", "desc": "Exporting Ledger Live logs may be necessary for troubleshooting purposes.", @@ -841,6 +846,10 @@ "title": "Something went wrong, please reconnect your device", "description": "{{message}}" }, + "UnexpectedBootloader": { + "title": "Opps, your device should not be in Bootloader mode", + "description": "Please restart your device or contact us" + }, "UserRefusedFirmwareUpdate": { "title": "Firmware update refused on device", "description": "Please retry or contact Ledger Support" diff --git a/yarn.lock b/yarn.lock index 5af319d7..399f121c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1701,9 +1701,9 @@ bip32-path "0.4.2" "@ledgerhq/hw-transport-node-hid@^4.32.0": - version "4.32.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.32.0.tgz#75fec81c44e9f8fbe0f918080e2b70e99de2a346" - integrity sha512-uZO+52TBxaYVhGIULHbhvyZWx+uLjvflDwfLicQR1eYxbYACB6xLXwq4sz9gL5He966t637Zx9iPsLi87rtqvQ== + version "4.33.3" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.33.3.tgz#5e96dca2be0a23d80814303f262398087b208a6a" + integrity sha512-hmNAm7k385RJXY38hVUpzYgGgyk9QjScD3erNlFCTO8FnnxmEJCFUmVhWkv4sTwufuUJSpXL3ZXXNZ44qLMJpg== dependencies: "@ledgerhq/hw-transport" "^4.32.0" lodash "^4.17.11" @@ -1725,10 +1725,10 @@ bindings "^1.3.0" nan "^2.6.2" -"@ledgerhq/live-common@4.8.0-beta.4": - version "4.8.0-beta.4" - resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-4.8.0-beta.4.tgz#291641f42a5cac8c26cf3baf0c303542509df86c" - integrity sha512-xmNLrljtCPSDJDiJndIlSX+wsgVQBNEZH25c+Dz3/uaZVtOVldE4iav7r7qKkGVNoUwvEhoqSAcjSuqKEFiBhg== +"@ledgerhq/live-common@4.8.0-beta.12": + version "4.8.0-beta.12" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-4.8.0-beta.12.tgz#4319aa397896f242d753ea63ff7ac4223788eb88" + integrity sha512-J2gaXqQkDuqZl2SgjNE7ZOSX0nMl9xqHu5jwHqiyBSlXvykdXWMmaPLcBcP8F+xszpKCIB0N6XaJFUAHHbD0Nw== dependencies: "@aeternity/ledger-app-api" "0.0.4" "@ledgerhq/hw-app-btc" "^4.32.0" @@ -4119,11 +4119,16 @@ binaryextensions@2: resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" integrity sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA== -bindings@^1.2.1, bindings@^1.3.0: +bindings@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" integrity sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw== +bindings@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" + integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew== + bip32-path@0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/bip32-path/-/bip32-path-0.4.2.tgz#5db0416ad6822712f077836e2557b8697c0c7c99" @@ -4440,7 +4445,7 @@ buffer-alloc-unsafe@^1.1.0: resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== -buffer-alloc@^1.1.0: +buffer-alloc@^1.1.0, buffer-alloc@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== @@ -4867,10 +4872,10 @@ chokidar@^2.0.0, chokidar@^2.0.2: optionalDependencies: fsevents "^1.2.2" -chownr@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== chrome-trace-event@^1.0.0: version "1.0.0" @@ -7488,6 +7493,11 @@ expand-template@^1.0.2: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" integrity sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -8282,7 +8292,7 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== @@ -8294,6 +8304,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.0.5: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" @@ -8997,7 +9019,7 @@ i18next@^11.2.2: resolved "https://registry.yarnpkg.com/i18next/-/i18next-11.3.3.tgz#a6ca3c2a93237c94e242bda7df3411588ac37ea1" integrity sha512-YR1p0IJCKbUxi9DKKb7SK5kQMVcUIUA1xxPlxr7mn3pvkFdEE1eZi/TiYC5eyOE6wvWYOb5xZc+1HVSD5dJXMg== -iconv-lite@0.4, iconv-lite@^0.4.17, iconv-lite@^0.4.22, iconv-lite@^0.4.23, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4, iconv-lite@^0.4.17, iconv-lite@^0.4.22, iconv-lite@^0.4.23, iconv-lite@~0.4.13: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== @@ -9009,6 +9031,13 @@ iconv-lite@0.4.19: resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" @@ -11114,18 +11143,18 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" - integrity sha512-/jAn9/tEX4gnpyRATxgHEOV6xbcyxgT7iUnxo9Y3+OB0zX00TgKIv/2FZCf5brBbICcwbLqVv2ImjvWWrQMSYw== +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" - integrity sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA== +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== dependencies: minipass "^2.2.1" @@ -11220,7 +11249,12 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.10.0, nan@^2.2.1, nan@^2.6.2, nan@^2.8.0, nan@^2.9.2: +nan@^2.10.0, nan@^2.8.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.0.tgz#9d443fdb5e13a20770cc5e602eee59760a685885" + integrity sha512-zT5nC0JhbljmyEf+Z456nvm7iO7XgRV2hYxoBtPpnyp+0Q4aCoP6uWNn76v/I6k2kCYNLWqWbwBWQcjsNI/bjw== + +nan@^2.2.1, nan@^2.6.2, nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== @@ -11242,15 +11276,20 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" + integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -needle@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" - integrity sha512-t/ZswCM9JTWjAdXS9VpvqhI2Ct2sL2MdY4fUXqGJaGBk13ge99ObqRksRTbBE56K+wxUXwwfZYOuZHifFW9q+Q== +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -11283,13 +11322,20 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" -node-abi@^2.0.0, node-abi@^2.2.0: +node-abi@^2.0.0: version "2.4.3" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.3.tgz#43666b7b17e57863e572409edbb82115ac7af28b" integrity sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg== dependencies: semver "^5.4.1" +node-abi@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.5.0.tgz#942e1a78bce764bc0c1672d5821e492b9d032052" + integrity sha512-9g2twBGSP6wIR5PW7tXvAWnEWKJDH/VskdXp168xsw9VVxpEGov8K4jsP4/VeoC7b2ZAyzckvMCuQuQlw44lXg== + dependencies: + semver "^5.4.1" + node-dir@0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d" @@ -11339,13 +11385,13 @@ node-gyp@^3.6.0: which "1" node-hid@^0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-0.7.3.tgz#736e9a4dee5eec96c20fbe301e0311bb185cb2f4" - integrity sha512-LOCqWqcOlng+Kn1Qj/54zrPVfCagg1O7RlSgMmugykBcoYvUud6BswTrJM2aXuBac+bCCm3lA2srRG8YfmyXZQ== + version "0.7.4" + resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-0.7.4.tgz#2db109acee654b56bf518ffb3fd92cf9cd0647c1" + integrity sha512-gvgNDPoszObn7avIDYMUvVv1T0xQB4/CZFJWckra/LXAc0qHYho4M1LCnCKlLIocL2R5/3qGv0J4AjRMdwgjxg== dependencies: bindings "^1.3.0" nan "^2.10.0" - prebuild-install "^4.0.0" + prebuild-install "^5.2.1" node-int64@^0.4.0: version "0.4.0" @@ -11407,13 +11453,29 @@ node-object-hash@^1.2.0: integrity sha512-JQVqSM5/mOaUoUhCYR0t1vgm8RFo7qpJtPvnoFCLeqQh1xrfmr3BCD3nGBnACzpIEF7F7EVgqGD3O4lao/BY/A== node-pre-gyp@^0.10.0: - version "0.10.2" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.2.tgz#e8945c20ef6795a20aac2b44f036eb13cf5146e3" - integrity sha512-16lql9QTqs6KsB9fl3neWyZm02KxIKdI9FlJjrB0y7eMTP5Nyz+xalwPbOlw3iw7EejllJPmlJSnY711PLD1ug== + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-pre-gyp@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" + integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" - needle "^2.2.0" + needle "^2.2.1" nopt "^4.0.1" npm-packlist "^1.1.6" npmlog "^4.0.2" @@ -11516,9 +11578,9 @@ normalize-url@^1.4.0, normalize-url@^1.9.1: sort-keys "^1.0.0" npm-bundled@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" - integrity sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow== + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-install-package@~2.1.0: version "2.1.0" @@ -11526,9 +11588,9 @@ npm-install-package@~2.1.0: integrity sha1-1+/jz816sAYUuJbqUxGdyaslkSU= npm-packlist@^1.1.6: - version "1.1.10" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" - integrity sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA== + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -12600,22 +12662,23 @@ prebuild-install@^2.0.0: tunnel-agent "^0.6.0" which-pm-runs "^1.0.0" -prebuild-install@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-4.0.0.tgz#206ce8106ce5efa4b6cf062fc8a0a7d93c17f3a8" - integrity sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA== +prebuild-install@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.2.2.tgz#237888f21bfda441d0ee5f5612484390bccd4046" + integrity sha512-4e8VJnP3zJdZv/uP0eNWmr2r9urp4NECw7Mt1OSAi3rcLrbBRxGiAkfUFtre2MhQ5wfREAjRV+K1gubvs/GPsA== dependencies: detect-libc "^1.0.3" - expand-template "^1.0.2" + expand-template "^2.0.3" github-from-package "0.0.0" minimist "^1.2.0" mkdirp "^0.5.1" + napi-build-utils "^1.0.1" node-abi "^2.2.0" noop-logger "^0.1.1" npmlog "^4.0.1" os-homedir "^1.0.1" pump "^2.0.1" - rc "^1.1.6" + rc "^1.2.7" simple-get "^2.7.0" tar-fs "^1.13.0" tunnel-agent "^0.6.0" @@ -14325,7 +14388,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== @@ -14335,6 +14398,11 @@ semver@^5.0.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== +semver@^5.3.0, semver@^5.4.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -15287,7 +15355,20 @@ tar-fs@^1.13.0: pump "^1.0.0" tar-stream "^1.1.2" -tar-stream@^1.1.2, tar-stream@^1.5.0: +tar-stream@^1.1.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar-stream@^1.5.0: version "1.6.1" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395" integrity sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA== @@ -15310,14 +15391,14 @@ tar@^2.0.0: inherits "2" tar@^4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" - integrity sha512-mq9ixIYfNF9SK0IS/h2HKMu8Q2iaCuhDDsZhdEag/FHv8fOaYld4vN7ouMgcSSt5WKZzPs8atclTcJm36OTh4w== + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== dependencies: - chownr "^1.0.1" + chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" + minipass "^2.3.4" + minizlib "^1.1.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.2" @@ -15455,7 +15536,7 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= -to-buffer@^1.1.0: +to-buffer@^1.1.0, to-buffer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== @@ -15977,12 +16058,12 @@ url@^0.11.0, url@~0.11.0: querystring "0.2.0" usb@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/usb/-/usb-1.3.3.tgz#4e8a4b44ab8833fa1c4fb99778ebae1d2d626970" - integrity sha512-WRBxI54yEs2QPj28G6kITI3Wu7VxrtHbqiDvDRUDKdg97lcK1pTP8y9LoDWF22OiCCrEvrdeq0lNcr84QOzjXQ== + version "1.5.0" + resolved "https://registry.yarnpkg.com/usb/-/usb-1.5.0.tgz#3e07b23c6dacf06a7c8801ae913926702a818218" + integrity sha512-/0stiQEmweuO2BKv2avzQQ8ypDUjo4Osz5sSEi+d0F4Rc+ddX1xED3uf4Tkelc1eADlfn0JQZYHP0bI7CNDA0Q== dependencies: nan "^2.8.0" - node-pre-gyp "^0.10.0" + node-pre-gyp "^0.11.0" use@^3.1.0: version "3.1.0" @@ -16791,9 +16872,9 @@ yallist@^2.1.2: integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== yaml-loader@^0.5.0: version "0.5.0"