Skip to content

Commit

Permalink
feat(suite): improve 'used elsehwere' screen; implement session owner
Browse files Browse the repository at this point in the history
  • Loading branch information
mroz22 committed Oct 29, 2024
1 parent c98f7f8 commit 41e1bb2
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/suite-web/e2e/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export default defineConfig({
return null;
},
stealBridgeSession: async () => {
const bridge = new BridgeTransport({ messages });
const bridge = new BridgeTransport({ messages, id: 'foo-bar' });
await bridge.init();
const enumerateRes = await bridge.enumerate();
if (!enumerateRes.success) return null;
Expand Down
2 changes: 2 additions & 0 deletions packages/suite/src/components/suite/ConnectDevicePrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ const getMessageId = ({
return isDesktop() ? 'TR_NO_TRANSPORT_DESKTOP' : 'TR_NO_TRANSPORT';
case 'device-bootloader':
return 'TR_DEVICE_CONNECTED_BOOTLOADER';
case 'device-unacquired':
return 'TR_DEVICE_CONNECTED_UNACQUIRED';
default: {
if (connected) {
return !showWarning ? 'TR_DEVICE_CONNECTED' : 'TR_DEVICE_CONNECTED_WRONG_STATE';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ describe('Preloader component', () => {

it('Unacquired device', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { type: 'unacquired' },
selectedDevice: {
transportSessionOwner: 'foo',
type: 'unacquired',
},
};

const store = initStore(
Expand All @@ -210,7 +213,10 @@ describe('Preloader component', () => {

it('Unreadable device: webusb HID', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { type: 'unreadable', error: 'LIBUSB_ERROR_ACCESS' },
selectedDevice: {
type: 'unreadable',
error: 'LIBUSB_ERROR_ACCESS',
},
};

const store = initStore(
Expand All @@ -233,7 +239,10 @@ describe('Preloader component', () => {
jest.spyOn(envUtils, 'isLinux').mockImplementation(() => true);

const device: DeepPartial<AppState['device']> = {
selectedDevice: { type: 'unreadable', error: 'LIBUSB_ERROR_ACCESS' },
selectedDevice: {
type: 'unreadable',
error: 'LIBUSB_ERROR_ACCESS',
},
};

const store = initStore(
Expand All @@ -256,7 +265,10 @@ describe('Preloader component', () => {
jest.spyOn(envUtils, 'isLinux').mockImplementation(() => false);

const device: DeepPartial<AppState['device']> = {
selectedDevice: { type: 'unreadable', error: 'LIBUSB_ERROR_ACCESS' },
selectedDevice: {
type: 'unreadable',
error: 'LIBUSB_ERROR_ACCESS',
},
};

const store = initStore(
Expand All @@ -277,7 +289,10 @@ describe('Preloader component', () => {

it('Unreadable device: unknown error', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { type: 'unreadable', error: 'Unexpected error' },
selectedDevice: {
type: 'unreadable',
error: 'Unexpected error',
},
};

const store = initStore(
Expand All @@ -298,7 +313,10 @@ describe('Preloader component', () => {

it('Unknown device (should never happen)', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { features: undefined },
selectedDevice: {
transportSessionOwner: 'foo',
features: undefined,
},
};

const store = initStore(
Expand All @@ -319,7 +337,10 @@ describe('Preloader component', () => {

it('Seedless device', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { mode: 'seedless', features: {} },
selectedDevice: {
mode: 'seedless',
features: {},
},
};

const store = initStore(
Expand Down Expand Up @@ -365,7 +386,10 @@ describe('Preloader component', () => {

it('Not initialized device', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { mode: 'initialize', features: {} },
selectedDevice: {
mode: 'initialize',
features: {},
},
};

const store = initStore(
Expand All @@ -387,7 +411,10 @@ describe('Preloader component', () => {

it('Bootloader device with installed firmware', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { mode: 'bootloader', features: { firmware_present: true } },
selectedDevice: {
mode: 'bootloader',
features: { firmware_present: true },
},
};

const store = initStore(
Expand All @@ -409,7 +436,10 @@ describe('Preloader component', () => {

it('Bootloader device without firmware', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { mode: 'bootloader', features: { firmware_present: false } },
selectedDevice: {
mode: 'bootloader',
features: { firmware_present: false },
},
};

const store = initStore(
Expand All @@ -431,7 +461,10 @@ describe('Preloader component', () => {

it('Required FW update device', () => {
const device: DeepPartial<AppState['device']> = {
selectedDevice: { firmware: 'required', features: {} },
selectedDevice: {
firmware: 'required',
features: {},
},
};

const store = initStore(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Translation, TroubleshootingTips } from 'src/components/suite';
import { useDevice, useDispatch } from 'src/hooks/suite';

export const DeviceAcquire = () => {
const { isLocked } = useDevice();
const { isLocked, device } = useDevice();
const dispatch = useDispatch();

const isDeviceLocked = isLocked();
Expand All @@ -25,6 +25,21 @@ export const DeviceAcquire = () => {
);

const tips = [
{
key: 'device-used-elsewhere',
heading: <Translation id="TR_DEVICE_CONNECTED_UNACQUIRED" />,
description: device?.transportSessionOwner ? (
<Translation
id="TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION"
values={{
transportSessionOwner: device.transportSessionOwner,
}}
/>
) : (
// legacy bridge does not share transportSessionOwner information
<Translation id="TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION_UNKNOWN_APP" />
),
},
{
key: 'device-acquire',
heading: <Translation id="TR_TROUBLESHOOTING_CLOSE_TABS" />,
Expand Down
3 changes: 2 additions & 1 deletion packages/suite/src/support/extraDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from '@suite-common/token-definitions';
import { selectSuiteSettings } from '../reducers/suite/suiteReducer';
import { addWalletThunk, openSwitchDeviceDialog } from 'src/actions/wallet/addWalletThunk';
import { isDesktop } from '@trezor/env-utils';

const connectSrc = resolveStaticPath('connect/');
// 'https://localhost:8088/';
Expand All @@ -50,7 +51,7 @@ const connectInitSettings = {
popup: false,
manifest: {
email: '[email protected]',
appUrl: '@trezor/suite',
appUrl: isDesktop() ? '@trezor/suite' : window.origin,
},
sharedLogger: false,
enableFirmwareHashCheck: true,
Expand Down
14 changes: 14 additions & 0 deletions packages/suite/src/support/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6788,6 +6788,20 @@ export default defineMessages({
id: 'TR_DEVICE_CONNECTED_BOOTLOADER_RECONNECT_IN_NORMAL_NO_TOUCH',
defaultMessage: 'Reconnect the device without touching the screen.',
},
TR_DEVICE_CONNECTED_UNACQUIRED: {
id: 'TR_DEVICE_CONNECTED_UNACQUIRED',
defaultMessage: 'Device used elsewhere',
},
TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION: {
id: 'TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION',
defaultMessage:
'App {transportSessionOwner} might be using the device right now. You may acquire the device for yourself.',
},
TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION_UNKNOWN_APP: {
id: 'TR_DEVICE_CONNECTED_UNACQUIRED_DESCRIPTION_UNKNOWN_APP',
defaultMessage:
'Another app might be using the device right now. You may acquire the device for yourself.',
},
TR_WIPE_OR_UPDATE: {
id: 'TR_WIPE_OR_UPDATE',
defaultMessage: 'Reset device or update firmware',
Expand Down
2 changes: 1 addition & 1 deletion suite-common/test-utils/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ type StringPath<T extends { path: DeviceUniquePath }> = Omit<T, 'path'> & { path
*/
const getConnectDevice = (dev?: Partial<StringPath<Device>>, feat?: Partial<Features>): Device => {
const path = DeviceUniquePath(dev?.path ?? '1');

if (dev && typeof dev.type === 'string' && dev.type === 'unreadable') {
return {
type: 'unreadable',
Expand All @@ -164,6 +163,7 @@ const getConnectDevice = (dev?: Partial<StringPath<Device>>, feat?: Partial<Feat
path,
label: 'Unacquired device',
name: 'name of unacquired device',
transportSessionOwner: 'another app name',
};
}

Expand Down

0 comments on commit 41e1bb2

Please sign in to comment.