From 40d44d8d5940d9c8d6e315a3b6ce19fb8dfaacee Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi Date: Wed, 25 May 2022 06:13:39 -0700 Subject: [PATCH] Add download robot credential button. Add timedate to messages in chat. --- frontend/src/components/EncryptedChat.js | 8 +++--- frontend/src/components/UserGenPage.js | 35 ++++++++++++++++++++---- frontend/src/utils/pgp.js | 35 +++++++++++++++--------- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/EncryptedChat.js b/frontend/src/components/EncryptedChat.js index c272a37b..ed92a1fb 100644 --- a/frontend/src/components/EncryptedChat.js +++ b/frontend/src/components/EncryptedChat.js @@ -208,7 +208,7 @@ class Chat extends Component { } - subheader={this.state.showPGP[props.index] ? props.message.encryptedMessage : props.message.plainTextMessage} + subheader={this.state.showPGP[props.index] ? {props.message.time}
{"Valid signature: " + props.message.validSignature}
{props.message.encryptedMessage}
: props.message.plainTextMessage} subheaderTypographyProps={{sx: {wordWrap: "break-word", width: '200px', color: '#444444', fontSize: this.state.showPGP[props.index]? 11 : null }}} /> @@ -256,7 +256,7 @@ class Chat extends Component { label={t("Type a message")} variant="standard" size="small" - helperText={this.state.connected ? null : t("Connecting...")} + helperText={this.state.connected ? (this.state.peer_pub_key ? null : t("Waiting for peer public key...")) : t("Connecting...")} value={this.state.value} onChange={e => { this.setState({ value: e.target.value }); @@ -266,7 +266,7 @@ class Chat extends Component { /> - + diff --git a/frontend/src/components/UserGenPage.js b/frontend/src/components/UserGenPage.js index 18dc2bda..883cc243 100644 --- a/frontend/src/components/UserGenPage.js +++ b/frontend/src/components/UserGenPage.js @@ -9,12 +9,14 @@ import SmartToyIcon from '@mui/icons-material/SmartToy'; import CasinoIcon from '@mui/icons-material/Casino'; import ContentCopy from "@mui/icons-material/ContentCopy"; import BoltIcon from '@mui/icons-material/Bolt'; +import DownloadIcon from '@mui/icons-material/Download'; import { RoboSatsNoTextIcon } from "./Icons"; import { sha256 } from 'js-sha256'; import { genBase62Token, tokenStrength } from "../utils/token"; import { genKey } from "../utils/pgp"; import { getCookie, writeCookie } from "../utils/cookies"; +import { saveAsJson } from "../utils/saveFile"; class UserGenPage extends Component { @@ -146,6 +148,16 @@ class UserGenPage extends Component { this.setState({openInfo: false}); }; + 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'), + }) + } + render() { const { t, i18n} = this.props; return ( @@ -208,11 +220,24 @@ class UserGenPage extends Component { }} InputProps={{ startAdornment: - - (navigator.clipboard.writeText(this.state.token) & this.props.setAppState({copiedToken:true}))}> - - - , +
+ + + + saveAsJson(this.state.nickname+'.json', this.createJsonFile())}> + + + + + + + (navigator.clipboard.writeText(this.state.token) & this.props.setAppState({copiedToken:true}))}> + + + + + +
, endAdornment: diff --git a/frontend/src/utils/pgp.js b/frontend/src/utils/pgp.js index 5e2a01dc..32947778 100644 --- a/frontend/src/utils/pgp.js +++ b/frontend/src/utils/pgp.js @@ -1,9 +1,18 @@ -import * as openpgp from 'openpgp/lightweight'; +import { + generateKey, + readKey, + readPrivateKey, + decryptKey, + encrypt, + decrypt, + createMessage, + readMessage +} from 'openpgp/lightweight'; // Generate KeyPair. Private Key is encrypted with the highEntropyToken export async function genKey(highEntropyToken) { - const keyPair = await openpgp.generateKey({ + const keyPair = await generateKey({ type: 'ecc', // Type of the key, defaults to ECC curve: 'curve25519', // ECC curve name, defaults to curve25519 userIDs: [{name: 'RoboSats Avatar ID'+ parseInt(Math.random() * 1000000)}], //Just for identification. Ideally it would be the avatar nickname, but the nickname is generated only after submission @@ -17,15 +26,15 @@ export async function genKey(highEntropyToken) { // Encrypt and sign a message export async function encryptMessage(plaintextMessage, ownPublicKeyArmored, peerPublicKeyArmored, privateKeyArmored, passphrase) { - const ownPublicKey = await openpgp.readKey({ armoredKey: ownPublicKeyArmored }); - const peerPublicKey = await openpgp.readKey({ armoredKey: peerPublicKeyArmored }); - const privateKey = await openpgp.decryptKey({ - privateKey: await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }), + const ownPublicKey = await readKey({ armoredKey: ownPublicKeyArmored }); + const peerPublicKey = await readKey({ armoredKey: peerPublicKeyArmored }); + const privateKey = await decryptKey({ + privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }), passphrase }); - const encryptedMessage = await openpgp.encrypt({ - message: await openpgp.createMessage({ text: plaintextMessage }), // input as Message object, message must be string + const encryptedMessage = await encrypt({ + message: await createMessage({ text: plaintextMessage }), // input as Message object, message must be string encryptionKeys: [ ownPublicKey, peerPublicKey ], signingKeys: privateKey // optional }); @@ -36,16 +45,16 @@ export async function encryptMessage(plaintextMessage, ownPublicKeyArmored, peer // Decrypt and check signature of a message export async function decryptMessage(encryptedMessage, publicKeyArmored, privateKeyArmored, passphrase) { - const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored }); - const privateKey = await openpgp.decryptKey({ - privateKey: await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }), + const publicKey = await readKey({ armoredKey: publicKeyArmored }); + const privateKey = await decryptKey({ + privateKey: await readPrivateKey({ armoredKey: privateKeyArmored }), passphrase }); - const message = await openpgp.readMessage({ + const message = await readMessage({ armoredMessage: encryptedMessage // parse armored message }); - const { data: decrypted, signatures } = await openpgp.decrypt({ + const { data: decrypted, signatures } = await decrypt({ message, verificationKeys: publicKey, // optional decryptionKeys: privateKey