2022-01-02 00:19:18 +00:00
|
|
|
import React, { Component } from "react";
|
2022-04-05 14:25:53 +00:00
|
|
|
import { withTranslation } from "react-i18next";
|
2022-05-08 15:43:08 +00:00
|
|
|
import { Button , Tooltip, Grid, Typography, TextField, ButtonGroup, CircularProgress, IconButton} from "@mui/material"
|
2022-01-02 21:41:22 +00:00
|
|
|
import { Link } from 'react-router-dom'
|
|
|
|
import Image from 'material-ui-image'
|
2022-05-08 15:43:08 +00:00
|
|
|
import { InfoDialog } from './Dialogs'
|
2022-04-05 14:25:53 +00:00
|
|
|
|
2022-01-30 15:18:03 +00:00
|
|
|
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
2022-01-30 13:18:32 +00:00
|
|
|
import CasinoIcon from '@mui/icons-material/Casino';
|
2022-01-18 13:20:19 +00:00
|
|
|
import ContentCopy from "@mui/icons-material/ContentCopy";
|
2022-03-27 12:09:51 +00:00
|
|
|
import BoltIcon from '@mui/icons-material/Bolt';
|
2022-05-25 13:13:39 +00:00
|
|
|
import DownloadIcon from '@mui/icons-material/Download';
|
2022-05-16 18:01:17 +00:00
|
|
|
import { RoboSatsNoTextIcon } from "./Icons";
|
2022-03-27 12:09:51 +00:00
|
|
|
|
2022-05-22 19:30:12 +00:00
|
|
|
import { sha256 } from 'js-sha256';
|
|
|
|
import { genBase62Token, tokenStrength } from "../utils/token";
|
2022-05-24 00:31:34 +00:00
|
|
|
import { genKey } from "../utils/pgp";
|
2022-06-20 14:26:19 +00:00
|
|
|
import { getCookie, writeCookie, deleteCookie } from "../utils/cookies";
|
2022-05-25 13:13:39 +00:00
|
|
|
import { saveAsJson } from "../utils/saveFile";
|
2022-07-04 18:42:04 +00:00
|
|
|
import { copyToClipboard } from "../utils/clipboard";
|
2022-05-22 19:30:12 +00:00
|
|
|
|
2022-04-05 14:25:53 +00:00
|
|
|
class UserGenPage extends Component {
|
2022-01-02 17:42:33 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2022-01-15 00:28:19 +00:00
|
|
|
openInfo: false,
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: false,
|
2022-05-02 19:28:34 +00:00
|
|
|
token: ""
|
2022-01-02 17:42:33 +00:00
|
|
|
};
|
2022-02-21 10:05:19 +00:00
|
|
|
|
2022-03-05 17:32:27 +00:00
|
|
|
this.refCode = this.props.match.params.refCode;
|
2022-05-02 19:28:34 +00:00
|
|
|
}
|
2022-02-21 10:05:19 +00:00
|
|
|
|
2022-05-02 19:28:34 +00:00
|
|
|
componentDidMount() {
|
2022-02-21 10:05:19 +00:00
|
|
|
// Checks in parent HomePage if there is already a nick and token
|
|
|
|
// Displays the existing one
|
|
|
|
if (this.props.nickname != null){
|
2022-05-02 19:28:34 +00:00
|
|
|
this.setState({
|
2022-02-21 10:05:19 +00:00
|
|
|
nickname: this.props.nickname,
|
2022-05-08 15:43:08 +00:00
|
|
|
token: this.props.token? this.props.token : "",
|
2022-06-20 18:48:42 +00:00
|
|
|
avatarUrl: '/static/assets/avatars/' + this.props.nickname + '.png',
|
2022-02-21 10:05:19 +00:00
|
|
|
loadingRobot: false
|
2022-05-02 19:28:34 +00:00
|
|
|
});
|
2022-02-21 10:05:19 +00:00
|
|
|
}
|
|
|
|
else{
|
2022-05-22 19:30:12 +00:00
|
|
|
var newToken = genBase62Token(36)
|
2022-05-02 19:28:34 +00:00
|
|
|
this.setState({
|
2022-02-21 10:05:19 +00:00
|
|
|
token: newToken
|
2022-05-02 19:28:34 +00:00
|
|
|
});
|
2022-02-21 10:05:19 +00:00
|
|
|
this.getGeneratedUser(newToken);
|
|
|
|
}
|
2022-01-02 17:42:33 +00:00
|
|
|
}
|
2022-01-02 18:27:40 +00:00
|
|
|
|
2022-01-29 19:51:26 +00:00
|
|
|
getGeneratedUser=(token)=>{
|
2022-05-22 19:30:12 +00:00
|
|
|
|
2022-05-23 11:21:01 +00:00
|
|
|
const strength = tokenStrength(token);
|
|
|
|
const refCode = this.refCode
|
|
|
|
|
|
|
|
const requestOptions = genKey(token).then(function(key) {
|
|
|
|
return {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
|
|
|
body: JSON.stringify({
|
|
|
|
token_sha256: sha256(token),
|
|
|
|
public_key: key.publicKeyArmored,
|
|
|
|
encrypted_private_key: key.encryptedPrivateKeyArmored,
|
|
|
|
unique_values: strength.uniqueValues,
|
|
|
|
counts: strength.counts,
|
|
|
|
length: token.length,
|
|
|
|
ref_code: refCode,
|
|
|
|
})
|
|
|
|
}}
|
|
|
|
);
|
|
|
|
|
|
|
|
console.log(requestOptions)
|
|
|
|
|
|
|
|
requestOptions.then((options) =>
|
|
|
|
fetch("/api/user/",options)
|
2022-05-22 22:12:25 +00:00
|
|
|
.then((response) => response.json())
|
2022-05-23 11:21:01 +00:00
|
|
|
.then((data) => { console.log(data) &
|
2022-05-22 22:12:25 +00:00
|
|
|
this.setState({
|
|
|
|
nickname: data.nickname,
|
|
|
|
bit_entropy: data.token_bits_entropy,
|
2022-06-20 18:48:42 +00:00
|
|
|
avatarUrl: '/static/assets/avatars/' + data.nickname + '.png',
|
2022-05-22 22:12:25 +00:00
|
|
|
shannon_entropy: data.token_shannon_entropy,
|
|
|
|
bad_request: data.bad_request,
|
|
|
|
found: data.found,
|
|
|
|
loadingRobot:false,
|
|
|
|
})
|
|
|
|
&
|
|
|
|
// Add nick and token to App state (token only if not a bad request)
|
|
|
|
(data.bad_request ? this.props.setAppState({
|
2022-01-02 18:27:40 +00:00
|
|
|
nickname: data.nickname,
|
2022-06-20 17:56:08 +00:00
|
|
|
avatarLoaded: false,
|
|
|
|
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
2022-06-21 11:16:54 +00:00
|
|
|
referralCode: data.referral_code,
|
|
|
|
earnedRewards: data.earned_rewards,
|
2022-06-20 17:56:08 +00:00
|
|
|
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
2022-05-22 22:12:25 +00:00
|
|
|
})
|
|
|
|
:
|
|
|
|
(this.props.setAppState({
|
|
|
|
nickname: data.nickname,
|
|
|
|
token: token,
|
|
|
|
avatarLoaded: false,
|
2022-06-20 17:56:08 +00:00
|
|
|
activeOrderId: data.active_order_id ? data.active_order_id : null,
|
|
|
|
lastOrderId: data.last_order_id ? data.last_order_id : null,
|
2022-06-21 11:16:54 +00:00
|
|
|
referralCode: data.referral_code,
|
|
|
|
earnedRewards: data.earned_rewards,
|
2022-05-23 11:21:01 +00:00
|
|
|
})) & writeCookie("robot_token",token)
|
|
|
|
& writeCookie("pub_key",data.public_key.split('\n').join('\\'))
|
|
|
|
& writeCookie("enc_priv_key",data.encrypted_private_key.split('\n').join('\\')))
|
2022-05-22 22:12:25 +00:00
|
|
|
&
|
|
|
|
// If the robot has been found (recovered) we assume the token is backed up
|
|
|
|
(data.found ? this.props.setAppState({copiedToken:true}) : null)
|
2022-05-23 11:21:01 +00:00
|
|
|
})
|
2022-05-22 22:12:25 +00:00
|
|
|
);
|
2022-01-02 18:27:40 +00:00
|
|
|
}
|
2022-05-02 19:28:34 +00:00
|
|
|
|
2022-01-03 01:31:28 +00:00
|
|
|
delGeneratedUser() {
|
|
|
|
const requestOptions = {
|
|
|
|
method: 'DELETE',
|
2022-01-06 12:32:17 +00:00
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
2022-01-03 01:31:28 +00:00
|
|
|
};
|
2022-01-09 15:24:41 +00:00
|
|
|
fetch("/api/user", requestOptions)
|
2022-04-05 14:25:53 +00:00
|
|
|
.then((response) => response.json());
|
2022-06-20 14:26:19 +00:00
|
|
|
|
|
|
|
deleteCookie("sessionid");
|
|
|
|
deleteCookie("robot_token");
|
|
|
|
deleteCookie("pub_key");
|
|
|
|
deleteCookie("enc_priv_key");
|
2022-01-03 01:31:28 +00:00
|
|
|
}
|
|
|
|
|
2022-01-30 13:18:32 +00:00
|
|
|
handleClickNewRandomToken=()=>{
|
2022-05-22 19:30:12 +00:00
|
|
|
var token = genBase62Token(36);
|
2022-01-30 13:18:32 +00:00
|
|
|
this.setState({
|
2022-05-03 20:21:04 +00:00
|
|
|
token: token,
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: true,
|
|
|
|
});
|
2022-05-03 20:21:04 +00:00
|
|
|
this.props.setAppState({copiedToken: true})
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleChangeToken=(e)=>{
|
|
|
|
this.setState({
|
2022-06-11 13:12:09 +00:00
|
|
|
token: e.target.value.split(' ').join(''),
|
2022-01-30 13:18:32 +00:00
|
|
|
tokenHasChanged: true,
|
2022-01-02 21:41:22 +00:00
|
|
|
})
|
2022-01-30 13:18:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleClickSubmitToken=()=>{
|
2022-02-01 19:43:33 +00:00
|
|
|
this.delGeneratedUser();
|
2022-01-30 13:18:32 +00:00
|
|
|
this.getGeneratedUser(this.state.token);
|
2022-05-03 20:21:04 +00:00
|
|
|
this.setState({loadingRobot: true, tokenHasChanged: false});
|
2022-06-20 18:48:42 +00:00
|
|
|
this.props.setAppState({avatarLoaded: false,
|
|
|
|
nickname: null,
|
|
|
|
token: null,
|
|
|
|
copiedToken: false,
|
|
|
|
lastOrderId: null,
|
|
|
|
activeOrderId: null});
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
2022-01-02 18:27:40 +00:00
|
|
|
|
2022-01-15 00:28:19 +00:00
|
|
|
handleClickOpenInfo = () => {
|
|
|
|
this.setState({openInfo: true});
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCloseInfo = () => {
|
|
|
|
this.setState({openInfo: false});
|
|
|
|
};
|
|
|
|
|
2022-05-25 13:13:39 +00:00
|
|
|
createJsonFile = () => {
|
|
|
|
return ({
|
|
|
|
"token":getCookie('robot_token'),
|
|
|
|
"token_shannon_entropy": this.state.shannon_entropy,
|
|
|
|
"token_bit_entropy": this.state.bit_entropy,
|
|
|
|
"public_key": getCookie('pub_key').split('\\').join('\n'),
|
|
|
|
"encrypted_private_key": getCookie('enc_priv_key').split('\\').join('\n'),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-01-02 17:42:33 +00:00
|
|
|
render() {
|
2022-04-05 14:25:53 +00:00
|
|
|
const { t, i18n} = this.props;
|
2022-01-02 17:42:33 +00:00
|
|
|
return (
|
2022-01-02 21:41:22 +00:00
|
|
|
<Grid container spacing={1}>
|
2022-03-15 18:20:57 +00:00
|
|
|
<Grid item>
|
2022-03-18 21:21:13 +00:00
|
|
|
<div className='clickTrough'/>
|
2022-03-15 18:20:57 +00:00
|
|
|
</Grid>
|
2022-01-30 13:18:32 +00:00
|
|
|
<Grid item xs={12} align="center" sx={{width:370, height:260}}>
|
|
|
|
{!this.state.loadingRobot ?
|
2022-01-18 13:20:19 +00:00
|
|
|
<div>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="h5" variant="h5">
|
2022-06-20 17:56:08 +00:00
|
|
|
<b>{this.state.nickname && getCookie("sessionid") ?
|
2022-03-27 12:09:51 +00:00
|
|
|
<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap', height:'45px'}}>
|
|
|
|
<BoltIcon sx={{ color: "#fcba03", height: '33px',width: '33px'}}/><a>{this.state.nickname}</a><BoltIcon sx={{ color: "#fcba03", height: '33px',width: '33px'}}/>
|
|
|
|
</div>
|
|
|
|
: ""}</b>
|
2022-01-18 13:20:19 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-05-02 19:28:34 +00:00
|
|
|
<Tooltip enterTouchDelay={0} title={t("This is your trading avatar")}>
|
2022-01-18 13:20:19 +00:00
|
|
|
<div style={{ maxWidth: 200, maxHeight: 200 }}>
|
2022-06-20 17:56:08 +00:00
|
|
|
<Image
|
|
|
|
className='newAvatar'
|
2022-05-02 19:28:34 +00:00
|
|
|
disableError={true}
|
|
|
|
cover={true}
|
2022-01-18 13:20:19 +00:00
|
|
|
color='null'
|
2022-06-20 18:48:42 +00:00
|
|
|
src={getCookie("sessionid") ? this.state.avatarUrl || "" : ""}
|
2022-01-18 13:20:19 +00:00
|
|
|
/>
|
2022-02-01 22:05:49 +00:00
|
|
|
</div>
|
|
|
|
</Tooltip><br/>
|
2022-01-18 13:20:19 +00:00
|
|
|
</Grid>
|
|
|
|
</div>
|
2022-01-30 13:18:32 +00:00
|
|
|
: <CircularProgress sx={{position: 'relative', top: 100, }}/>}
|
2022-01-02 21:41:22 +00:00
|
|
|
</Grid>
|
|
|
|
{
|
|
|
|
this.state.found ?
|
|
|
|
<Grid item xs={12} align="center">
|
2022-05-23 11:21:01 +00:00
|
|
|
<Typography variant="subtitle2" color='primary'>
|
2022-04-05 14:25:53 +00:00
|
|
|
{this.state.found ? t("A robot avatar was found, welcome back!"):null}<br/>
|
2022-01-02 21:41:22 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
:
|
2022-01-03 14:27:25 +00:00
|
|
|
""
|
2022-01-02 21:41:22 +00:00
|
|
|
}
|
2022-01-18 13:20:19 +00:00
|
|
|
<Grid container align="center">
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-30 15:18:03 +00:00
|
|
|
<TextField sx={{maxWidth: 280}}
|
2022-05-23 11:21:01 +00:00
|
|
|
error={this.state.bad_request ? true : false}
|
2022-04-05 14:25:53 +00:00
|
|
|
label={t("Store your token safely")}
|
2022-05-02 19:28:34 +00:00
|
|
|
required={true}
|
2022-01-18 13:20:19 +00:00
|
|
|
value={this.state.token}
|
|
|
|
variant='standard'
|
|
|
|
helperText={this.state.bad_request}
|
|
|
|
size='small'
|
|
|
|
onChange={this.handleChangeToken}
|
2022-01-30 13:18:32 +00:00
|
|
|
onKeyPress={(e) => {
|
|
|
|
if (e.key === 'Enter') {
|
|
|
|
this.handleClickSubmitToken();
|
|
|
|
}
|
|
|
|
}}
|
2022-01-30 15:18:03 +00:00
|
|
|
InputProps={{
|
|
|
|
startAdornment:
|
2022-05-25 13:13:39 +00:00
|
|
|
<div style={{width:50, minWidth:50, position:'relative',left:-6}}>
|
2022-05-26 21:16:02 +00:00
|
|
|
<Grid container>
|
2022-05-25 13:13:39 +00:00
|
|
|
<Grid item xs={6}>
|
|
|
|
<Tooltip enterTouchDelay={250} title={t("Save token and PGP credentials to file")}>
|
2022-05-26 21:16:02 +00:00
|
|
|
<span>
|
2022-05-30 11:19:12 +00:00
|
|
|
<IconButton
|
|
|
|
color="primary"
|
2022-05-30 21:19:16 +00:00
|
|
|
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
2022-05-30 11:19:12 +00:00
|
|
|
onClick={()=> saveAsJson(this.state.nickname+'.json', this.createJsonFile())}
|
|
|
|
>
|
2022-05-25 13:13:39 +00:00
|
|
|
<DownloadIcon sx={{width:22, height:22}}/>
|
|
|
|
</IconButton>
|
2022-05-26 21:16:02 +00:00
|
|
|
</span>
|
2022-05-25 13:13:39 +00:00
|
|
|
</Tooltip>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={6}>
|
|
|
|
<Tooltip disableHoverListener enterTouchDelay={0} title={t("Copied!")}>
|
2022-05-30 11:19:12 +00:00
|
|
|
<IconButton
|
2022-05-30 21:19:16 +00:00
|
|
|
color={this.props.copiedToken ? "inherit":"primary"}
|
2022-05-30 11:19:12 +00:00
|
|
|
disabled={!(getCookie('robot_token')==this.state.token) || !this.props.avatarLoaded}
|
2022-07-04 18:42:04 +00:00
|
|
|
onClick={()=> (copyToClipboard(getCookie('robot_token')) & this.props.setAppState({copiedToken:true}))}
|
2022-05-30 11:19:12 +00:00
|
|
|
>
|
|
|
|
<ContentCopy sx={{width:18, height:18}}/>
|
2022-05-25 13:13:39 +00:00
|
|
|
</IconButton>
|
|
|
|
</Tooltip>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</div>,
|
2022-01-30 15:18:03 +00:00
|
|
|
endAdornment:
|
2022-05-02 19:28:34 +00:00
|
|
|
<Tooltip enterTouchDelay={250} title={t("Generate a new token")}>
|
2022-02-01 22:05:49 +00:00
|
|
|
<IconButton onClick={this.handleClickNewRandomToken}><CasinoIcon/></IconButton>
|
|
|
|
</Tooltip>,
|
2022-01-30 15:18:03 +00:00
|
|
|
}}
|
2022-01-18 13:20:19 +00:00
|
|
|
/>
|
|
|
|
</Grid>
|
2022-01-03 14:27:25 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-02-02 09:29:05 +00:00
|
|
|
{this.state.tokenHasChanged ?
|
|
|
|
<Button type="submit" size='small' onClick= {this.handleClickSubmitToken}>
|
|
|
|
<SmartToyIcon sx={{width:18, height:18}} />
|
2022-04-05 14:25:53 +00:00
|
|
|
<span> {t("Generate Robot")}</span>
|
2022-02-02 09:29:05 +00:00
|
|
|
</Button>
|
|
|
|
:
|
2022-05-02 19:28:34 +00:00
|
|
|
<Tooltip enterTouchDelay={0} enterDelay={500} enterNextDelay={2000} title={t("You must enter a new token first")}>
|
2022-02-02 16:26:10 +00:00
|
|
|
<div>
|
2022-02-02 09:29:05 +00:00
|
|
|
<Button disabled={true} type="submit" size='small' >
|
2022-01-30 15:18:03 +00:00
|
|
|
<SmartToyIcon sx={{width:18, height:18}} />
|
2022-04-05 14:25:53 +00:00
|
|
|
<span>{t("Generate Robot")}</span>
|
2022-01-30 13:18:32 +00:00
|
|
|
</Button>
|
2022-02-02 16:26:10 +00:00
|
|
|
</div>
|
|
|
|
</Tooltip>
|
2022-02-02 09:29:05 +00:00
|
|
|
}
|
2022-01-03 14:27:25 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<ButtonGroup variant="contained" aria-label="outlined primary button group">
|
2022-06-04 17:29:21 +00:00
|
|
|
<Button disabled={this.state.loadingRobot || !(this.props.token ? getCookie('robot_token')==this.props.token : true )} color='primary' to='/make/' component={Link}>{t("Make Order")}</Button>
|
2022-04-10 15:11:11 +00:00
|
|
|
<Button color='inherit' style={{color: '#111111'}} onClick={this.handleClickOpenInfo}>{t("Info")}</Button>
|
2022-07-10 10:54:00 +00:00
|
|
|
<InfoDialog open={Boolean(this.state.openInfo)} maxAmount='3,000,000' onClose = {this.handleCloseInfo}/>
|
2022-06-04 17:29:21 +00:00
|
|
|
<Button disabled={this.state.loadingRobot || !(this.props.token ? getCookie('robot_token')==this.props.token : true )} color='secondary' to='/book/' component={Link}>{t("View Book")}</Button>
|
2022-01-03 14:27:25 +00:00
|
|
|
</ButtonGroup>
|
|
|
|
</Grid>
|
2022-03-15 18:20:57 +00:00
|
|
|
|
2022-05-02 19:28:34 +00:00
|
|
|
<Grid item xs={12} align="center" sx={{width:370}}>
|
2022-03-15 18:20:57 +00:00
|
|
|
<Grid item>
|
2022-03-18 21:21:13 +00:00
|
|
|
<div style={{height:40}}/>
|
2022-03-15 18:20:57 +00:00
|
|
|
</Grid>
|
|
|
|
<div style={{width:370, left:30}}>
|
2022-05-02 19:28:34 +00:00
|
|
|
<Grid container align="center">
|
2022-03-15 18:20:57 +00:00
|
|
|
<Grid item xs={0.8}/>
|
|
|
|
<Grid item xs={7.5} align="right">
|
|
|
|
<Typography component="h5" variant="h5">
|
2022-04-05 14:25:53 +00:00
|
|
|
{t("Simple and Private LN P2P Exchange")}
|
2022-03-15 18:20:57 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={2.5} align="left">
|
2022-03-17 00:42:07 +00:00
|
|
|
<RoboSatsNoTextIcon color="primary" sx={{height:72, width:72}}/>
|
2022-03-15 18:20:57 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</div>
|
2022-01-02 21:41:22 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
2022-01-02 17:42:33 +00:00
|
|
|
);
|
|
|
|
}
|
2022-04-05 14:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-04-15 16:22:49 +00:00
|
|
|
export default withTranslation()(UserGenPage);
|