clone custom name

pull/2/merge
Szymon Lesisz 6 years ago
parent ff7f79eb14
commit 2beaeff8ac

@ -56,7 +56,7 @@ export const ConfirmUnverifiedAddress = (props: Props) => {
return (
<div className="confirm-address-unverified">
<button className="close-modal transparent" onClick={ onCancel }></button>
<h3>{ device.instanceLabel } is not connected</h3>
<h3>{ device.label } is not connected</h3>
<p>To prevent phishing attacks, you should verify the address on your TREZOR first. Please reconnect your device to continue with the verification process.</p>
<button onClick={ event => {
onCancel();
@ -74,7 +74,7 @@ export const ConfirmUnverifiedAddress = (props: Props) => {
return (
<div className="confirm-address-unverified">
<button className="close-modal transparent" onClick={ onCancel }></button>
<h3>{ device.instanceLabel } is unavailable</h3>
<h3>{ device.label } is unavailable</h3>
<p>To prevent phishing attacks, you should verify the address on your TREZOR first. { enable } passphrase settings to continue with the verification process.</p>
<button onClick={ event => {
onCancel();

@ -5,6 +5,10 @@ import React from 'react';
import type { Props } from './index';
const Confirmation = (props: Props) => {
if (!props.modal.opened) return null;
const { device } = props.modal;
const {
amount,
address,
@ -18,8 +22,8 @@ const Confirmation = (props: Props) => {
return (
<div className="confirm-tx">
<div className="header">
<h3>Confirm transaction on your TREZOR</h3>
<p>Details are shown on device</p>
<h3>Confirm transaction on { device.label } device</h3>
<p>Details are shown on display</p>
</div>
<div className="content">
<label>Send </label>

@ -1,21 +1,63 @@
/* @flow */
'use strict';
import React from 'react';
import React, { Component } from 'react';
import { getNewInstance } from '../../reducers/TrezorConnectReducer'
import type { Props } from './index';
const RememberDevice = (props: Props) => {
if (!props.modal.opened) return null;
const { device } = props.modal;
const { onCancel, onDuplicateDevice } = props.modalActions;
return (
<div className="duplicate">
<h3>Clone { device.instanceLabel }?</h3>
<p>This will create new instance of device which can be used with different passphrase</p>
<button onClick={ event => onDuplicateDevice( { ...device, instanceLabel: "TODO: user label from input" } ) }>Create new instance</button>
<button className="white" onClick={ onCancel }>Cancel</button>
</div>
);
type State = {
defaultName: string;
instanceName: ?string;
}
export default RememberDevice;
export default class DuplicateDevice extends Component<Props, State> {
state: State;
constructor(props: Props) {
super(props);
const device = props.modal.opened ? props.modal.device : null;
if (!device) return;
const instance = getNewInstance(props.connect.devices, device);
this.state = {
defaultName: `${device.label} (${instance.toString()})`,
instanceName: null
}
}
onNameChange = (value: string): void => {
this.setState({
instanceName: value.length > 0 ? value : null
});
}
render() {
if (!this.props.modal.opened) return null;
const { device } = this.props.modal;
const { onCancel, onDuplicateDevice } = this.props.modalActions;
return (
<div className="duplicate">
<h3>Clone { device.label }?</h3>
<p>This will create new instance of device which can be used with different passphrase</p>
<label>Instance name</label>
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
placeholder={ this.state.defaultName }
onChange={ event => this.onNameChange(event.currentTarget.value) }
defaultValue={ this.state.instanceName } />
<button onClick={ event => onDuplicateDevice( { ...device, instanceName: this.state.instanceName } ) }>Create new instance</button>
<button className="white" onClick={ onCancel }>Cancel</button>
</div>
);
}
}

@ -10,7 +10,7 @@ const InvalidPin = (props: Props) => {
const { device } = props.modal;
return (
<div className="pin">
<h3>Entered PIN for { device.label } is not correct.</h3>
<h3>Entered PIN for { device.label } is not correct</h3>
<p>Retrying...</p>
</div>
);

@ -2,12 +2,17 @@
'use strict';
import React from 'react';
import type { Props } from './index';
const Confirmation = (props: Props) => {
if (!props.modal.opened) return null;
const { device } = props.modal;
const Confirmation = () => {
return (
<div className="confirm-tx">
<div className="header">
<h3>Complete the action on your TREZOR device</h3>
<h3>Complete the action on { device.label } device</h3>
</div>
</div>
);

@ -67,16 +67,15 @@ export default class RememberDevice extends Component<Props, State> {
const { onForgetDevice, onRememberDevice } = this.props.modalActions;
let label = device.label;
let devicePlural: string = "device or to remember it";
if (instances && instances.length > 1) {
const devicePlural: string = instances && instances.length > 1 ? "devices or to remember them" : "device or to remember it";
if (instances && instances.length > 0) {
label = instances.map((instance, index) => {
let comma: string = '';
if (index > 0) comma = ', ';
return (
<span key={ index }>{ comma }{ instance.instanceLabel }</span>
);
})
devicePlural = "devices or to remember them";
});
}
return (
<div className="remember">

@ -51,6 +51,7 @@ export type TrezorDevice = {
state: ?string;
instance?: number;
instanceLabel: string;
instanceName: ?string;
features?: Features;
unacquired?: boolean;
acquiring: boolean;

@ -81,6 +81,24 @@ export const isSavedDevice = (state: State, device: any): ?Array<TrezorDevice> =
});
}
export const getNewInstance = (devices: Array<TrezorDevice>, device: Device | TrezorDevice): number => {
const affectedDevices: Array<TrezorDevice> = devices.filter(d => d.features && device.features && d.features.device_id === device.features.device_id)
.sort((a, b) => {
if (!a.instance) {
return -1;
} else {
return !b.instance || a.instance > b.instance ? 1 : -1;
}
});
const instance: number = affectedDevices.reduce((inst, dev) => {
return dev.instance ? dev.instance + 1 : inst + 1;
}, 0);
return instance;
}
const mergeDevices = (current: TrezorDevice, upcoming: Object): TrezorDevice => {
// do not merge if passphrase protection was changed
@ -95,7 +113,7 @@ const mergeDevices = (current: TrezorDevice, upcoming: Object): TrezorDevice =>
if (upcoming.label !== current.label) {
instanceLabel = upcoming.label
if (typeof current.instance === 'number') {
instanceLabel += ` (${current.instance})`;
instanceLabel += ` (${current.instanceName || current.instance})`;
}
}
@ -112,21 +130,14 @@ const mergeDevices = (current: TrezorDevice, upcoming: Object): TrezorDevice =>
acquiring: typeof upcoming.acquiring === 'boolean' ? upcoming.acquiring : current.acquiring,
ts: typeof upcoming.ts === 'number' ? upcoming.ts : current.ts,
}
// corner-case: trying to merge unacquired device with acquired
// make sure that sensitive fields will not be changed and device will remain acquired
if (upcoming.unacquired && current.state) {
dev.instanceLabel = current.instanceLabel;
dev.unacquired = false;
dev.features = current.features;
dev.label = current.label;
dev.unacquired = false;
} else if (!upcoming.unacquired && current.unacquired) {
// dev.instanceLabel = upcoming.label;
// if (typeof dev.instance === 'number') {
// dev.instanceLabel = `${upcoming.label} TODO:(${dev.instance})`;
// }
}
return dev;
}
@ -151,14 +162,17 @@ const addDevice = (state: State, device: Device): State => {
}
if (affectedDevices.length > 0 ) {
// replace existing values
// const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => mergeDevices(d, { ...device, connected: true} ));
// check if freshly added device has different "passphrase_protection" settings
let cloneInstance: number = 1;
let hasDifferentPassphraseSettings: boolean = false;
let hasInstancesWithPassphraseSettings: boolean = false;
const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => {
if (d.features && d.features.passphrase_protection === device.features.passphrase_protection) {
cloneInstance = 0;
hasInstancesWithPassphraseSettings = true;
return mergeDevices(d, { ...device, connected: true, available: true } );
} else {
hasDifferentPassphraseSettings = true;
if (d.instance && cloneInstance > 0) {
cloneInstance = d.instance + 1;
}
@ -167,9 +181,12 @@ const addDevice = (state: State, device: Device): State => {
}
});
if (cloneInstance > 0) {
// edge case: freshly connected device has different "passphrase_protection" than saved instances
// need to automatically create another instance with default instance name
if (hasDifferentPassphraseSettings && !hasInstancesWithPassphraseSettings) {
// TODO: instance should be calculated form affectedDevice
const instance = cloneInstance; //new Date().getTime();
// const instance = cloneInstance; //new Date().getTime();
const instance = getNewInstance(affectedDevices, device);
const newDevice: TrezorDevice = {
...device,
@ -182,14 +199,15 @@ const addDevice = (state: State, device: Device): State => {
state: null,
instance,
instanceLabel: `${device.label} (${instance})`,
instanceName: null,
ts: new Date().getTime(),
}
changedDevices.push(newDevice);
}
newState.devices = otherDevices.concat(changedDevices);
} else {
const newDevice: TrezorDevice = {
...device,
acquiring: false,
@ -199,14 +217,11 @@ const addDevice = (state: State, device: Device): State => {
path: device.path,
label: device.label,
state: null,
// instance: 0,
instanceLabel: device.label,
instanceName: null,
ts: new Date().getTime(),
}
newState.devices.push(newDevice);
// const clone = { ...newDevice, instance: 1, instanceLabel: device.label + '#1' };
// newState.devices.push(clone);
}
return newState;
@ -251,9 +266,15 @@ const changeDevice = (state: State, device: Object): State => {
if (affectedDevices.length > 0) {
const isAffectedUnacquired: number = affectedDevices.findIndex(d => d.unacquired);
if (isAffectedUnacquired >= 0 && affectedDevices.length > 1){
affectedDevices.splice(isAffectedUnacquired, 1);
}
// if (isAffectedUnacquired >= 0 && affectedDevices.length > 1){
if (isAffectedUnacquired >= 0){
// TODO: should unacquired device be removed? or merged?
//affectedDevices.splice(isAffectedUnacquired, 1);
} else {
// replace existing values
const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => mergeDevices(d, device));
newState.devices = otherDevices.concat(changedDevices);
}
// else if (isAffectedUnacquired >= 0 && !device.unacquired && affectedDevices.length > 1) {
// affectedDevices.splice(isAffectedUnacquired, 1);
@ -263,12 +284,6 @@ const changeDevice = (state: State, device: Object): State => {
if (state.selectedDevice && device.path === state.selectedDevice.id && affectedDevices.length > 1) {
// affectedDevices = affectedDevices.filter(d => d.path !== state.selectedDevice.id && d.features);
}
// replace existing values
const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => mergeDevices(d, device));
newState.devices = otherDevices.concat(changedDevices);
}
return newState;
@ -336,30 +351,33 @@ const devicesFromLocalStorage = (devices: Array<any>): Array<TrezorDevice> => {
const duplicate = (state: State, device: TrezorDevice): State => {
const newState: State = { ...state };
const affectedDevices: Array<TrezorDevice> = state.devices.filter(d => d.features && device.features && d.features.device_id === device.features.device_id)
.sort((a, b) => {
if (!a.instance) {
return -1;
} else {
return !b.instance || a.instance > b.instance ? 1 : -1;
}
});
// const affectedDevices: Array<TrezorDevice> = state.devices.filter(d => d.features && device.features && d.features.device_id === device.features.device_id)
// .sort((a, b) => {
// if (!a.instance) {
// return -1;
// } else {
// return !b.instance || a.instance > b.instance ? 1 : -1;
// }
// });
const instance: number = affectedDevices.reduce((inst, dev) => {
return dev.instance ? dev.instance + 1 : inst + 1;
}, 0);
// const instance: number = affectedDevices.reduce((inst, dev) => {
// return dev.instance ? dev.instance + 1 : inst + 1;
// }, 0);
const instance: number = getNewInstance(state.devices, device);
const newDevice: TrezorDevice = {
...device,
acquiring: false,
// acquiring: false,
remember: false,
connected: device.connected,
available: device.available,
path: device.path,
label: device.label,
// connected: device.connected,
// available: device.available,
// path: device.path,
// label: device.label,
state: null,
instance,
instanceLabel: `${device.label} (${instance})`,
// instanceLabel: `${device.label} (${instance})`,
instanceLabel: `${device.label} (${ device.instanceName || instance })`,
ts: new Date().getTime(),
}
newState.devices.push(newDevice);
@ -450,7 +468,7 @@ export default function connect(state: State = initialState, action: Action): St
case DEVICE.CONNECT_UNACQUIRED :
return addDevice(state, action.device);
case DEVICE.CHANGED :
return changeDevice(state, { ...action.device, connected: true, available: true });
return changeDevice(state, { ...action.device, connected: true, available: true }); // TODO: check if available will propagate to unavailable
case DEVICE.DISCONNECT :
case DEVICE.DISCONNECT_UNACQUIRED :
return disconnectDevice(state, action.device);

Loading…
Cancel
Save