From 538844697810e892073e1d93be1e912333595706 Mon Sep 17 00:00:00 2001
From: pbca26
Date: Sun, 12 Nov 2017 21:34:34 +0300
Subject: [PATCH 1/5] harden security, reset input fields
---
.../importKeyModal/importKeyModal.js | 13 ++++
.../importKeyModal/importKeyModal.render.js | 11 ++--
.../settings/settings.exportKeysPanel.js | 45 +++++++++-----
react/src/components/login/login.js | 60 +++++++++++++------
react/src/components/login/login.render.js | 4 ++
react/src/components/overrides.scss | 10 ++++
6 files changed, 106 insertions(+), 37 deletions(-)
diff --git a/react/src/components/dashboard/importKeyModal/importKeyModal.js b/react/src/components/dashboard/importKeyModal/importKeyModal.js
index 5e130ce18..e3a87e779 100755
--- a/react/src/components/dashboard/importKeyModal/importKeyModal.js
+++ b/react/src/components/dashboard/importKeyModal/importKeyModal.js
@@ -187,6 +187,19 @@ class ImportKeyModal extends React.Component {
);
}
});
+
+ this.state({
+ passphraseWif: null,
+ passphraseAddress: null,
+ wifkeysPassphrase: null,
+ wifkeysPassphraseTextarea: null,
+ importWithRescan: this.state.importWithRescan ? false : this.state.importWithRescan,
+ });
+
+ // reset input vals
+ this.refs.wif
+ this.refs.wifkeysPassphrase.value = '';
+ this.refs.wifkeysPassphraseTextarea.value = '';
}
generateKeysFromPassphrase() {
diff --git a/react/src/components/dashboard/importKeyModal/importKeyModal.render.js b/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
index 053d9ce56..6fcfbdda9 100644
--- a/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
+++ b/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
@@ -26,23 +26,25 @@ export const ImportKeyModalRender = function() {
{ translate('IMPORT_KEY.NOTICE') }: { translate('IMPORT_KEY.NOTICE_DESC') }.
{ translate('IMPORT_KEY.KMD_RESCAN_WARNING_TIME') }.
-
+
{ this.state.passphraseAddress &&
this.state.passphraseWif &&
@@ -118,6 +120,7 @@ export const ImportKeyModalRender = function() {
type="text"
className="form-control"
name="wif"
+ ref="wif"
onChange={ this.updateInput }
value={ this.state.wif } />
diff --git a/react/src/components/dashboard/settings/settings.exportKeysPanel.js b/react/src/components/dashboard/settings/settings.exportKeysPanel.js
index e3c50be84..7b7cf168a 100644
--- a/react/src/components/dashboard/settings/settings.exportKeysPanel.js
+++ b/react/src/components/dashboard/settings/settings.exportKeysPanel.js
@@ -28,7 +28,12 @@ class ExportKeysPanel extends React.Component {
props.Dashboard.activeSection !== 'settings') {
this.setState(Object.assign({}, this.state, {
keys: null,
+ wifkeysPassphrase: '',
}));
+
+ // reset input vals
+ this.refs.wifkeysPassphrase.value = '';
+ this.refs.wifkeysPassphraseTextarea.value = '';
}
}
@@ -46,8 +51,12 @@ class ExportKeysPanel extends React.Component {
} else {
this.setState(Object.assign({}, this.state, {
keys: keys.result,
+ wifkeysPassphrase: '',
}));
- console.warn(keys);
+
+ // reset input vals
+ this.refs.wifkeysPassphrase.value = '';
+ this.refs.wifkeysPassphraseTextarea.value = '';
}
})
}
@@ -162,22 +171,24 @@ class ExportKeysPanel extends React.Component {
-
{ this.state.keys &&
-
-
- |
- { translate('SETTINGS.ADDRESS_LIST') }
- |
-
- { translate('SETTINGS.WIF_KEY_LIST') }
- |
-
- { this.renderWifKeys() }
+
+
+
+ |
+ { translate('SETTINGS.ADDRESS_LIST') }
+ |
+
+ { translate('SETTINGS.WIF_KEY_LIST') }
+ |
+
+ { this.renderWifKeys() }
+
diff --git a/react/src/components/login/login.js b/react/src/components/login/login.js
index 55fc37ab5..e0e19691c 100644
--- a/react/src/components/login/login.js
+++ b/react/src/components/login/login.js
@@ -8,7 +8,8 @@ import {
startInterval,
getDexCoins,
triggerToaster,
- toggleLoginSettingsModal
+ toggleLoginSettingsModal,
+ stopInterval,
} from '../../actions/actionCreators';
import Config from '../../config';
import Store from '../../store';
@@ -197,6 +198,7 @@ class Login extends React.Component {
if (props.Login.pinList === 'no pins') {
props.Login.pinList = [];
}
+
if (props &&
props.Main &&
props.Main.isLoggedIn) {
@@ -215,21 +217,48 @@ class Login extends React.Component {
if (props &&
props.Main &&
!props.Main.isLoggedIn) {
+ document.body.className = 'page-login layout-full page-dark';
+
+ if (props.Interval &&
+ props.Interval.interval &&
+ props.Interval.interval.sync) {
+ Store.dispatch(
+ stopInterval(
+ 'sync',
+ props.Interval.interval
+ )
+ );
+ }
+
this.setState({
display: true,
activeLoginSection: this.state.activeLoginSection !== 'signup' ? 'login' : 'signup',
});
+ }
+ if (props.Main &&
+ props.Main.total === 0) {
document.body.className = 'page-login layout-full page-dark';
+
+ if (props.Interval &&
+ props.Interval.interval &&
+ props.Interval.interval.sync) {
+ Store.dispatch(
+ stopInterval(
+ 'sync',
+ props.Interval.interval
+ )
+ );
+ }
}
if (this.state.activeLoginSection !== 'signup' &&
props &&
props.Main &&
props.Main.isLoggedIn) {
- this.setState({
- activeLoginSection: 'activateCoin',
- });
+ this.setState({
+ activeLoginSection: 'activateCoin',
+ });
}
}
@@ -286,12 +315,6 @@ class Login extends React.Component {
}
loginSeed() {
- // reset the login pass phrase values so that when the user logs out, the values are clear
- this.setState({
- loginPassphrase: null,
- loginPassPhraseSeedType: null,
- });
-
if (this.state.shouldEncryptSeed) {
Store.dispatch(encryptPassphrase(this.state.loginPassphrase, this.state.encryptKey, this.state.pubKey));
}
@@ -306,6 +329,16 @@ class Login extends React.Component {
shepherdElectrumCoins()
);
}
+
+ // reset the login pass phrase values so that when the user logs out, the values are clear
+ this.setState({
+ loginPassphrase: '',
+ loginPassPhraseSeedType: null,
+ });
+
+ // reset login input vals
+ this.refs.loginPassphrase.value = '';
+ this.refs.loginPassphraseEdit.value = '';
}
loadPinList() {
@@ -362,13 +395,6 @@ class Login extends React.Component {
}
execWalletCreate() {
- /*Store.dispatch(
- createNewWallet(
- this.state.randomSeedConfirm,
- this.props.Dashboard.activeHandle
- )
- );*/
-
Store.dispatch(
shepherdElectrumAuth(this.state.randomSeedConfirm)
);
diff --git a/react/src/components/login/login.render.js b/react/src/components/login/login.render.js
index c3f97f250..bf919b4d6 100644
--- a/react/src/components/login/login.render.js
+++ b/react/src/components/login/login.render.js
@@ -55,13 +55,17 @@ const LoginRender = function () {
type="password"
className={ !this.state.seedInputVisibility ? 'form-control' : 'hide' }
name="loginPassphrase"
+ ref="loginPassphraseEdit"
onChange={ this.updateLoginPassPhraseInput }
onKeyDown={ (event) => this.handleKeydown(event) }
+ autoComplete="off"
value={ this.state.loginPassphrase || '' } />
diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss
index 8253a30cf..d5365690c 100644
--- a/react/src/components/overrides.scss
+++ b/react/src/components/overrides.scss
@@ -511,4 +511,14 @@ select{
.coind-remove-icon {
transform: rotate(45deg);
top: 45px;
+}
+
+.coind-remove-icon-spv {
+ top: 19px;
+}
+
+.no-borders {
+ tbody > tr > td {
+ border: none;
+ }
}
\ No newline at end of file
From 4937f1764d4a07613b64ac3a1bd6c62b83c77697 Mon Sep 17 00:00:00 2001
From: pbca26
Date: Sun, 12 Nov 2017 23:58:13 +0300
Subject: [PATCH 2/5] header coin name fix
---
.../src/components/dashboard/walletsMain/walletsMain.render.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/react/src/components/dashboard/walletsMain/walletsMain.render.js b/react/src/components/dashboard/walletsMain/walletsMain.render.js
index b14303a32..3e4a1a526 100644
--- a/react/src/components/dashboard/walletsMain/walletsMain.render.js
+++ b/react/src/components/dashboard/walletsMain/walletsMain.render.js
@@ -5,6 +5,7 @@ import SendCoin from '../sendCoin/sendCoin';
import WalletsProgress from '../walletsProgress/walletsProgress';
import WalletsData from '../walletsData/walletsData';
import ReceiveCoin from '../receiveCoin/receiveCoin';
+import { getCoinTitle } from '../../../util/coinHelper';
const WalletsMainRender = function() {
return (
@@ -22,7 +23,7 @@ const WalletsMainRender = function() {
- { this.props.ActiveCoin.coin }
+ { getCoinTitle(this.props.ActiveCoin.coin).name }
From 277d3fd02180310fdff8632efa2ce3a51e8c1e1c Mon Sep 17 00:00:00 2001
From: pbca26
Date: Mon, 13 Nov 2017 01:36:38 +0300
Subject: [PATCH 3/5] spv lock, logout
---
.../src/components/dashboard/navbar/navbar.js | 25 +++++++++++++++++++
.../dashboard/navbar/navbar.render.js | 16 ++++++++++++
2 files changed, 41 insertions(+)
diff --git a/react/src/components/dashboard/navbar/navbar.js b/react/src/components/dashboard/navbar/navbar.js
index a5e9042ea..ec62a38bb 100755
--- a/react/src/components/dashboard/navbar/navbar.js
+++ b/react/src/components/dashboard/navbar/navbar.js
@@ -6,6 +6,10 @@ import {
stopInterval,
startInterval,
displayImportKeyModal,
+ shepherdElectrumLock,
+ shepherdElectrumLogout,
+ getDexCoins,
+ activeHandle,
} from '../../../actions/actionCreators';
import Store from '../../../store';
import Config from '../../../config';
@@ -23,6 +27,24 @@ class Navbar extends React.Component {
this.openDropMenu = this.openDropMenu.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this._checkAC = this._checkAC.bind(this);
+ this.spvLock = this.spvLock.bind(this);
+ this.spvLogout = this.spvLogout.bind(this);
+ }
+
+ spvLock() {
+ shepherdElectrumLock()
+ .then((res) => {
+ Store.dispatch(getDexCoins());
+ Store.dispatch(activeHandle());
+ });
+ }
+
+ spvLogout() {
+ shepherdElectrumLogout()
+ .then((res) => {
+ Store.dispatch(getDexCoins());
+ Store.dispatch(activeHandle());
+ });
}
componentWillMount() {
@@ -106,6 +128,9 @@ const mapStateToProps = (state) => {
Interval: {
interval: state.Interval.interval,
},
+ Main: {
+ isLoggedIn: state.Main.isLoggedIn,
+ },
};
};
diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js
index fca2a46fa..6a8bb05cc 100644
--- a/react/src/components/dashboard/navbar/navbar.render.js
+++ b/react/src/components/dashboard/navbar/navbar.render.js
@@ -109,6 +109,22 @@ const NavbarRender = function() {
{ translate('ABOUT.ABOUT_AGAMA') }
+ { this.props.Main &&
+ this.props.Main.isLoggedIn &&
+
+
+ Lock
+
+
+ }
+ { this.props.Main &&
+ this.props.Main.isLoggedIn &&
+
+
+ Logout
+
+
+ }
From c48bd079e9a37d8fe9835b402220775d0a191b79 Mon Sep 17 00:00:00 2001
From: pbca26
Date: Mon, 13 Nov 2017 01:37:04 +0300
Subject: [PATCH 4/5] remove coin extended
---
react/src/actions/actions/addCoin.js | 2 +-
react/src/actions/actions/coinList.js | 57 ++++++++++++++++++-
react/src/components/addcoin/addcoin.js | 2 +-
.../claimInterestModal/claimInterestModal.js | 4 +-
.../dashboard/coinTile/coinTileItem.js | 32 +++++++++--
.../dashboard/coinTile/coinTileItem.render.js | 22 ++-----
.../importKeyModal/importKeyModal.js | 4 +-
.../importKeyModal/importKeyModal.render.js | 2 +-
.../settings/settings.exportKeysPanel.js | 6 +-
react/src/components/login/login.js | 28 +++++----
react/src/components/login/login.render.js | 6 +-
react/src/components/overrides.scss | 1 +
12 files changed, 118 insertions(+), 48 deletions(-)
diff --git a/react/src/actions/actions/addCoin.js b/react/src/actions/actions/addCoin.js
index ab2e2181d..642631db7 100644
--- a/react/src/actions/actions/addCoin.js
+++ b/react/src/actions/actions/addCoin.js
@@ -243,7 +243,7 @@ export function shepherdHerd(coin, mode, path, startupParams) {
console.warn(acData);
dispatch(
triggerToaster(
- `Error starting ${coin} daemon. Port ${acData.rpc} is already taken!`, // translate
+ translate('TOASTR.ERROR_STARTING_DAEMON', coin) + ' ' + translate('TOASTR.PORT_IS_TAKEN', acData.rpc),
translate('TOASTR.SERVICE_NOTIFICATION'),
'error',
false
diff --git a/react/src/actions/actions/coinList.js b/react/src/actions/actions/coinList.js
index c078fb0ba..7a69e197e 100644
--- a/react/src/actions/actions/coinList.js
+++ b/react/src/actions/actions/coinList.js
@@ -1,6 +1,54 @@
import { triggerToaster } from '../actionCreators';
import Config from '../../config';
+export function shepherdElectrumLock() {
+ return new Promise((resolve, reject) => {
+ fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/lock`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: '',
+ })
+ .catch((error) => {
+ console.log(error);
+ dispatch(
+ triggerToaster(
+ 'shepherdElectrumLock',
+ 'Error',
+ 'error'
+ )
+ );
+ })
+ .then(response => response.json())
+ .then(json => resolve(json))
+ });
+}
+
+export function shepherdElectrumLogout() {
+ return new Promise((resolve, reject) => {
+ fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/logout`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: '',
+ })
+ .catch((error) => {
+ console.log(error);
+ dispatch(
+ triggerToaster(
+ 'shepherdElectrumLogout',
+ 'Error',
+ 'error'
+ )
+ );
+ })
+ .then(response => response.json())
+ .then(json => resolve(json))
+ });
+}
+
export function shepherdStopCoind(coin) {
return new Promise((resolve, reject) => {
fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/coind/stop`, {
@@ -25,14 +73,19 @@ export function shepherdStopCoind(coin) {
});
}
-export function shepherdRemoveCoin(coin) {
+export function shepherdRemoveCoin(coin, mode) {
return new Promise((resolve, reject) => {
fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/coins/remove`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
- body: coin === 'KMD' ? '' : JSON.stringify({ chain: coin }),
+ body: JSON.stringify(coin === 'KMD' && mode === 'native' ? {
+ mode,
+ } : {
+ mode,
+ chain: coin,
+ }),
})
.catch((error) => {
console.log(error);
diff --git a/react/src/components/addcoin/addcoin.js b/react/src/components/addcoin/addcoin.js
index 56e9f57d3..43237f64c 100644
--- a/react/src/components/addcoin/addcoin.js
+++ b/react/src/components/addcoin/addcoin.js
@@ -128,7 +128,7 @@ class AddCoin extends React.Component {
addCoinProps.display !== this.state.display) {
this.setState(Object.assign({}, this.state, {
display: addCoinProps.display,
- modalClassName: addCoinProps.display ? 'show fade' : 'show fade',
+ modalClassName: 'show fade',
}));
setTimeout(() => {
diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js
index 13cff7858..8fe21d3ea 100755
--- a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js
+++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js
@@ -35,7 +35,9 @@ class ClaimInterestModal extends React.Component {
}
componentWillMount() {
- this.loadListUnspent();
+ if (this.props.ActiveCoin.mode === 'native') {
+ this.loadListUnspent();
+ }
}
loadListUnspent() {
diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js
index e3d3e4493..cbd3c6419 100644
--- a/react/src/components/dashboard/coinTile/coinTileItem.js
+++ b/react/src/components/dashboard/coinTile/coinTileItem.js
@@ -30,7 +30,7 @@ import Config from '../../../config';
import CoinTileItemRender from './coinTileItem.render';
-const SPV_DASHBOARD_UPDATE_TIMEOUT = 60000;
+const SPV_DASHBOARD_UPDATE_TIMEOUT = 10000;
const ACTIVE_HANDLE_TIMEOUT_COIND_NATIVE = 15000;
const COIND_DOWN_MODAL_FETCH_FAILURES_THRESHOLD = window.require('electron').remote.getCurrentWindow().appConfig.failedRPCAttemptsThreshold || 10;
@@ -43,6 +43,28 @@ class CoinTileItem extends React.Component {
this.autoSetActiveCoin = this.autoSetActiveCoin.bind(this);
}
+ renderStopCoinButton() {
+ if (this.props.Main &&
+ this.props.Main.coins &&
+ this.props.Main.coins.native &&
+ this.props.Main.coins.native.length) {
+ return true;
+ }
+ }
+
+ renderRemoveCoinButton() {
+ if (this.props.Main &&
+ this.props.Main.coins &&
+ ((this.props.Main.coins.native &&
+ this.props.Main.coins.native.length &&
+ this.state.appConfig &&
+ !this.state.appConfig.stopNativeDaemonsOnQuit) ||
+ (this.props.Main.coins.spv &&
+ this.props.Main.coins.spv.length))) {
+ return true;
+ }
+ }
+
autoSetActiveCoin() {
const modes = [
'native',
@@ -97,8 +119,8 @@ class CoinTileItem extends React.Component {
});
}
- removeCoin(coin) {
- shepherdRemoveCoin(coin)
+ removeCoin(coin, mode) {
+ shepherdRemoveCoin(coin, mode)
.then((res) => {
Store.dispatch(
triggerToaster(
@@ -189,9 +211,7 @@ class CoinTileItem extends React.Component {
)
);
}
- }
-
- if (mode === 'spv') {
+ } else if (mode === 'spv') {
Store.dispatch(shepherdElectrumBalance(coin, this.props.Dashboard.electrumCoins[coin].pub));
Store.dispatch(shepherdElectrumTransactions(coin, this.props.Dashboard.electrumCoins[coin].pub));
}
diff --git a/react/src/components/dashboard/coinTile/coinTileItem.render.js b/react/src/components/dashboard/coinTile/coinTileItem.render.js
index f7b111708..08578f0e6 100644
--- a/react/src/components/dashboard/coinTile/coinTileItem.render.js
+++ b/react/src/components/dashboard/coinTile/coinTileItem.render.js
@@ -24,29 +24,17 @@ const CoinTileItemRender = function() {
- { item.mode === 'native' &&
- this.props.Main &&
- this.props.Main.coins &&
- this.props.Main.coins.native &&
- this.props.Main.coins.native.length &&
- this.props.Main.coins.native.length > 1 &&
+ { this.renderStopCoinButton() &&
this.stopCoind(item.coin) }
+ onClick={ () => this.stopCoind(item.coin, item.mode) }
title="Stop"
className="icon fa-stop-circle coind-stop-icon">
}
- { item.mode === 'native' &&
- this.props.Main &&
- this.props.Main.coins &&
- this.props.Main.coins.native &&
- this.props.Main.coins.native.length &&
- this.props.Main.coins.native.length > 1 &&
- this.state.appConfig &&
- !this.state.appConfig.stopNativeDaemonsOnQuit &&
+ { this.renderRemoveCoinButton() &&
this.removeCoin(item.coin) }
+ onClick={ () => this.removeCoin(item.coin, item.mode) }
title="Remove"
- className="icon fa-plus-circle coind-remove-icon">
+ className={ 'icon fa-plus-circle ' + (item.mode === 'spv' ? 'coind-remove-icon coind-remove-icon-spv' : 'coind-remove-icon') }>
}
{ this.props.Dashboard &&
this.props.Dashboard.electrumCoins &&
diff --git a/react/src/components/dashboard/importKeyModal/importKeyModal.js b/react/src/components/dashboard/importKeyModal/importKeyModal.js
index e3a87e779..824f4b41d 100755
--- a/react/src/components/dashboard/importKeyModal/importKeyModal.js
+++ b/react/src/components/dashboard/importKeyModal/importKeyModal.js
@@ -77,11 +77,11 @@ class ImportKeyModal extends React.Component {
this.setState({
trimPassphraseTimer: _trimPassphraseTimer,
- [e.target.name]: newValue,
+ [e.target.name === 'wifkeysPassphraseTextarea' ? 'wifkeysPassphrase' : e.target.name]: newValue,
});
} else {
this.setState({
- [e.target.name]: e.target.value,
+ [e.target.name === 'wifkeysPassphraseTextarea' ? 'wifkeysPassphrase' : e.target.name]: e.target.value,
});
}
}
diff --git a/react/src/components/dashboard/importKeyModal/importKeyModal.render.js b/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
index 6fcfbdda9..a13065781 100644
--- a/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
+++ b/react/src/components/dashboard/importKeyModal/importKeyModal.render.js
@@ -43,7 +43,7 @@ export const ImportKeyModalRender = function() {
autoComplete="off"
className={ this.state.seedInputVisibility ? 'form-control' : 'hide' }
id="wifkeysPassphraseTextarea"
- name="wifkeysPassphrase"
+ name="wifkeysPassphraseTextarea"
ref="wifkeysPassphraseTextarea"
onChange={ this.updateInput }
value={ this.state.wifkeysPassphrase }>
diff --git a/react/src/components/dashboard/settings/settings.exportKeysPanel.js b/react/src/components/dashboard/settings/settings.exportKeysPanel.js
index 7b7cf168a..6fcada6a4 100644
--- a/react/src/components/dashboard/settings/settings.exportKeysPanel.js
+++ b/react/src/components/dashboard/settings/settings.exportKeysPanel.js
@@ -125,11 +125,11 @@ class ExportKeysPanel extends React.Component {
this.setState({
trimPassphraseTimer: _trimPassphraseTimer,
- [e.target.name]: newValue,
+ [e.target.name === 'wifkeysPassphraseTextarea' ? 'wifkeysPassphrase' : e.target.name]: newValue,
});
} else {
this.setState({
- [e.target.name]: e.target.value,
+ [e.target.name === 'wifkeysPassphraseTextarea' ? 'wifkeysPassphrase' : e.target.name]: e.target.value,
});
}
}
@@ -189,7 +189,7 @@ class ExportKeysPanel extends React.Component {
autoComplete="off"
id="wifkeysPassphraseTextarea"
ref="wifkeysPassphraseTextarea"
- name="wifkeysPassphrase"
+ name="wifkeysPassphraseTextarea"
onChange={ this.updateInput }
value={ this.state.wifkeysPassphrase }>
this.handleKeydown(event) }
autoComplete="off"
@@ -63,8 +63,8 @@ const LoginRender = function () {