feat(JWT): Added JWT token to Configure View

This commit is contained in:
Daniel Gonzalez
2020-06-23 18:40:58 -04:00
parent e5e601a9ea
commit e88e022b6a
7 changed files with 245 additions and 36 deletions
+122 -10
View File
@@ -1,17 +1,31 @@
import React from "react"
import { Content, Row, Col, Box } from "adminlte-2-react"
import PropTypes from "prop-types"
import { Content, Row, Col, Box, Inputs, Button } from "adminlte-2-react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import BchWallet from "minimal-slp-wallet"
class Audit extends React.Component {
state = {}
const { Text } = Inputs
let _this
class Configure extends React.Component {
constructor(props) {
super(props)
_this = this
this.state = {
JWT: "",
errMsg: "",
}
_this.BchWallet = BchWallet
}
render() {
return (
<Content>
<Row>
<Col sm={3} />
<Col sm={6}>
<Col sm={12}>
<Box className="hover-shadow border-none mt-2">
<Row>
<Col sm={12} className="text-center">
@@ -38,19 +52,117 @@ class Audit extends React.Component {
</p>
<p>
This is just a placeholder. This View will allow the user
to pick alternate back-end servers. The default will
be <a href="https://fullstack.cash" target="_blank" rel="noreferrer">FullStack.cash</a>
to pick alternate back-end servers. The default will be{" "}
<a
href="https://fullstack.cash"
target="_blank"
rel="noreferrer"
>
FullStack.cash
</a>
</p>
</Box>
</Col>
</Row>
</Box>
</Col>
<Col sm={3} />
<Col sm={12}>
<Box className="hover-shadow border-none mt-2">
<Row>
<Col sm={12} className="text-center">
<h1>
<FontAwesomeIcon
className="title-icon"
size="xs"
icon={"coins"}
/>
<span>JWT</span>
</h1>
<Box className="border-none">
<Text
id="jwt"
name="JWT"
placeholder="Enter FullStack.cash JWT"
label="FullStack.cash JWT"
labelPosition="above"
onChange={_this.handleUpdate}
/>
<Button
text="Update"
type="primary"
className="btn-lg"
onClick={_this.updateJWT}
/>
</Box>
</Col>
<Col sm={12} className="text-center">
{_this.state.errMsg && (
<p className="error-color">{_this.state.errMsg}</p>
)}
</Col>
</Row>
</Box>
</Col>
</Row>
</Content>
)
}
componentDidMount() {
_this.setJwt()
}
setJwt() {
const { JWT } = _this.props.walletInfo
if (JWT) {
const jwtElem = document.getElementById("jwt")
jwtElem.value = JWT
}
}
handleUpdate(event) {
let value = event.target.value
_this.setState({
[event.target.name]: value,
})
console.log(_this.state.JWT)
}
async updateJWT() {
try {
const { mnemonic } = _this.props.walletInfo
const apiToken = _this.state.JWT
// Update instance with JWT
if (mnemonic && apiToken) {
const bchWalletLib = new _this.BchWallet(mnemonic)
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
_this.props.setBchWallet(bchWalletLib)
}
const walletInfo = _this.props.walletInfo
walletInfo.JWT = apiToken
_this.props.setWalletInfo(walletInfo)
} catch (error) {
console.warn(error)
_this.setState({
errMsg: error.message,
})
}
}
// Reset form and component state
resetValues() {
_this.setState({
JWT: "",
errMsg: "",
})
const jwtElem = document.getElementById("jwt")
jwtElem.value = ""
}
}
Configure.propTypes = {
setWalletInfo: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired,
setBchWallet: PropTypes.func.isRequired,
}
export default Audit
export default Configure
+19 -10
View File
@@ -39,8 +39,6 @@ class AdminLTEPage extends React.Component {
<Item icon="fas-coins" key="Tokens" text="Tokens" />,
<Item icon="fa-qrcode" key="qrReader" text="Qr Scanner" />,
<Item icon="fas-cog" key="Configure" text="Configure" />,
]
render() {
@@ -67,13 +65,20 @@ class AdminLTEPage extends React.Component {
<div className="components-container">
{_this.state.section === "Wallet" && (
<Wallet
setWallet={_this.props.setWallet}
setWalletInfo={_this.props.setWalletInfo}
walletInfo={_this.props.walletInfo}
updateBalance={_this.props.updateBalance}
setBchWallet={_this.props.setBchWallet}
/>
)}
{_this.state.section === "Tokens" && <Tokens />}
{_this.state.section === "Configure" && <Configure />}
{_this.state.section === "Configure" && (
<Configure
walletInfo={_this.props.walletInfo}
setWalletInfo={_this.props.setWalletInfo}
setBchWallet={_this.props.setBchWallet}
/>
)}
{_this.state.section === "Audit" && <Audit />}
</div>
</Layout>
@@ -92,9 +97,11 @@ class AdminLTEPage extends React.Component {
async getBalance() {
try {
const { mnemonic } = _this.props.walletInfo
if (mnemonic) {
const bchWalletLib = new _this.BchWallet(mnemonic)
if (mnemonic && _this.props.bchWallet) {
const bchWalletLib = _this.props.bchWallet
await bchWalletLib.walletInfoPromise
const myBalance = await bchWalletLib.getBalance()
_this.props.updateBalance(myBalance)
}
@@ -229,10 +236,12 @@ class AdminLTEPage extends React.Component {
}
// Props prvided by redux
AdminLTEPage.propTypes = {
walletInfo: PropTypes.object.isRequired,
bchBalance: PropTypes.number.isRequired,
setWallet: PropTypes.func.isRequired,
updateBalance: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired, // wallet info
bchBalance: PropTypes.number.isRequired, // bch balance
setWalletInfo: PropTypes.func.isRequired, // set wallet info
updateBalance: PropTypes.func.isRequired, // update bch balance
setBchWallet: PropTypes.func.isRequired, // set minimal-slp-wallet instance
bchWallet:PropTypes.object, // get minimal-slp-wallet instance
}
export default AdminLTEPage
+21 -2
View File
@@ -51,7 +51,23 @@ class NewWallet extends React.Component {
async createWallet() {
try {
const currentWallet = _this.props.walletInfo
if (currentWallet.mnemonic) {
console.warn("Wallet already exists")
/*
* TODO: notify the user that if it has an existing wallet,
* it will get overwritten
*/
}
const bchWalletLib = new _this.BchWallet()
const apiToken = currentWallet.JWT
if (apiToken) {
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
}
await bchWalletLib.walletInfoPromise // Wait for wallet to be created.
const walletInfo = bchWalletLib.walletInfo
@@ -60,15 +76,18 @@ class NewWallet extends React.Component {
const myBalance = await bchWalletLib.getBalance()
// Update redux state
_this.props.setWallet(walletInfo)
_this.props.setWalletInfo(walletInfo)
_this.props.updateBalance(myBalance)
_this.props.setBchWallet(bchWalletLib)
} catch (error) {
console.error(error)
}
}
}
NewWallet.propTypes = {
setWallet: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired,
setWalletInfo: PropTypes.func.isRequired,
updateBalance: PropTypes.func.isRequired,
setBchWallet: PropTypes.func.isRequired,
}
export default NewWallet
+22 -2
View File
@@ -100,16 +100,34 @@ class ImportWallet extends React.Component {
try {
_this.validateInputs()
const currentWallet = _this.props.walletInfo
if (currentWallet.mnemonic) {
console.warn("Wallet already exists")
/*
* TODO: notify the user that it has an existing wallet,
* and it will get overwritten
*/
}
const bchWalletLib = new _this.BchWallet(_this.state.mnemonic)
const apiToken = currentWallet.JWT
if (apiToken) {
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: apiToken })
}
await bchWalletLib.walletInfoPromise // Wait for wallet to be created.
const walletInfo = bchWalletLib.walletInfo
walletInfo.from = "imported"
const myBalance = await bchWalletLib.getBalance()
// Update redux state
_this.props.setWallet(walletInfo)
_this.props.setWalletInfo(walletInfo)
_this.props.updateBalance(myBalance)
_this.props.setBchWallet(bchWalletLib)
// Reset form and component state
_this.resetValues()
@@ -154,7 +172,9 @@ class ImportWallet extends React.Component {
}
}
ImportWallet.propTypes = {
setWallet: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired,
setWalletInfo: PropTypes.func.isRequired,
updateBalance: PropTypes.func.isRequired,
setBchWallet: PropTypes.func.isRequired,
}
export default ImportWallet
+8 -3
View File
@@ -20,7 +20,9 @@ class Wallet extends React.Component {
<Content>
<NewWallet
updateBalance={_this.props.updateBalance}
setWallet={_this.props.setWallet}
setWalletInfo={_this.props.setWalletInfo}
setBchWallet={_this.props.setBchWallet}
walletInfo={_this.props.walletInfo}
/>
{_this.props.walletInfo.mnemonic &&
@@ -30,7 +32,9 @@ class Wallet extends React.Component {
<ImportWallet
updateBalance={_this.props.updateBalance}
setWallet={_this.props.setWallet}
setWalletInfo={_this.props.setWalletInfo}
setBchWallet={_this.props.setBchWallet}
walletInfo={_this.props.walletInfo}
/>
{_this.props.walletInfo.mnemonic &&
@@ -46,9 +50,10 @@ class Wallet extends React.Component {
}
Wallet.propTypes = {
setWallet: PropTypes.func.isRequired,
setWalletInfo: PropTypes.func.isRequired,
walletInfo: PropTypes.object.isRequired,
updateBalance: PropTypes.func.isRequired,
setBchWallet: PropTypes.func.isRequired,
}
export default Wallet
+10 -4
View File
@@ -5,17 +5,23 @@ let AdminLTE =
typeof window !== `undefined`
? require("../components/admin-lte").default
: null
const mapStateToProps = ({ walletInfo, bchBalance }) => {
return { walletInfo,bchBalance }
// Maps the props that are going to be sended
// to the component connected with Redux
const mapStateToProps = ({ walletInfo, bchBalance, bchWallet }) => {
return { walletInfo, bchBalance, bchWallet }
}
// Send each action of the reducer as props
// to the component connected with Redux
const mapDispatchToProps = dispatch => {
return {
setWallet: value => dispatch({ type: `SET_WALLET`, value }),
updateBalance: value =>dispatch({ type: `UPDATE_BALANCE`, value })
setWalletInfo: value => dispatch({ type: `SET_WALLET_INFO`, value }),
updateBalance: value => dispatch({ type: `UPDATE_BALANCE`, value }),
setBchWallet: value => dispatch({ type: `SET_BCH_WALLET`, value }),
}
}
// Component connected with redux
let ConnectedDashboard = AdminLTE
? connect(mapStateToProps, mapDispatchToProps)(AdminLTE)
: null
+43 -5
View File
@@ -1,14 +1,25 @@
import { createStore as reduxCreateStore } from "redux"
// Wallet from localStorage
import { getWalletInfo, setWalletInfo } from "../components/localWallet"
import BchWallet from "minimal-slp-wallet"
const reducer = (state, action) => {
// Update walletInfo state property
if (action.type === `SET_WALLET`) {
setWalletInfo(action.value) // Add wallet to local storage
if (action.type === `SET_WALLET_INFO`) {
const walletInfo = action.value
// persist JWT when create or import wallet
if (state.walletInfo.JWT && !walletInfo.JWT) {
walletInfo.JWT = state.walletInfo.JWT
}
setWalletInfo(walletInfo) // Add wallet to local storage
return Object.assign({}, state, {
walletInfo: action.value,
walletInfo: walletInfo,
})
}
// Update bchBalance state property
@@ -16,9 +27,17 @@ const reducer = (state, action) => {
// Convert satoshis to bch
const satoshis = action.value
const bch = satoshis / 100000000
return Object.assign({}, state, {
bchBalance: Number(bch.toFixed(8)),
})
}
// Adds the minimal-slp-wallet instance to the Redux state
if (action.type === `SET_BCH_WALLET`) {
return Object.assign({}, state, {
bchWallet: action.value,
})
}
return state
@@ -27,9 +46,28 @@ const reducer = (state, action) => {
// Wallet info from local storage
const localWallet = getWalletInfo()
// Creates an instance of minimal-slp-wallet, with
// the local storage information if it exists
const instanceWallet = () => {
try {
if (!localWallet.mnemonic) return null
const bchWalletLib = new BchWallet(localWallet.mnemonic)
const jwtToken = localWallet.JWT
if (jwtToken) {
bchWalletLib.bchjs = new bchWalletLib.BCHJS({ apiToken: jwtToken })
}
return bchWalletLib
} catch (error) {
console.warn(error)
}
}
// initial state
const initialState = {
walletInfo: localWallet.mnemonic ? localWallet : {},
bchBalance: 0,
walletInfo: localWallet.mnemonic ? localWallet : {}, // Object wallet info
bchBalance: 0, // Wallet Balance
bchWallet: instanceWallet(), // minimal-slp-wallet instance
}
const createStore = () => reduxCreateStore(reducer, initialState)