diff --git a/frontend/package.json b/frontend/package.json index f7426a92..e3c78b16 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "0.2.2", + "version": "0.2.3", "description": "", "main": "index.js", "scripts": { diff --git a/frontend/src/components/TradeBox/EncryptedChat.js b/frontend/src/components/TradeBox/EncryptedChat.js deleted file mode 100644 index 9da9b485..00000000 --- a/frontend/src/components/TradeBox/EncryptedChat.js +++ /dev/null @@ -1,565 +0,0 @@ -import React, { Component } from 'react'; -import { withTranslation } from 'react-i18next'; -import { - Button, - IconButton, - Badge, - Tooltip, - TextField, - Grid, - Container, - Card, - CardHeader, - Paper, - Avatar, - Typography, -} from '@mui/material'; -import ReconnectingWebSocket from 'reconnecting-websocket'; -import { encryptMessage, decryptMessage } from '../../pgp'; -import { saveAsJson } from '../../utils'; -import { AuditPGPDialog } from '../Dialogs'; -import RobotAvatar from '../RobotAvatar'; -import { systemClient } from '../../services/System'; -import { websocketClient } from '../../services/Websocket'; - -// Icons -import CheckIcon from '@mui/icons-material/Check'; -import CloseIcon from '@mui/icons-material/Close'; -import ContentCopy from '@mui/icons-material/ContentCopy'; -import VisibilityIcon from '@mui/icons-material/Visibility'; -import CircularProgress from '@mui/material/CircularProgress'; -import KeyIcon from '@mui/icons-material/Key'; -import { ExportIcon } from '../Icons'; - -class Chat extends Component { - constructor(props) { - super(props); - } - - state = { - own_pub_key: systemClient.getCookie('pub_key').split('\\').join('\n'), - own_enc_priv_key: systemClient.getCookie('enc_priv_key').split('\\').join('\n'), - peer_pub_key: null, - token: systemClient.getCookie('robot_token'), - messages: [], - value: '', - connected: false, - connection: null, - peer_connected: false, - audit: false, - showPGP: new Array(), - waitingEcho: false, - lastSent: '---BLANK---', - latestIndex: 0, - scrollNow: false, - }; - - componentDidMount() { - websocketClient - .open(`ws://${window.location.host}/ws/chat/${this.props.orderId}/`) - .then((connection) => { - console.log('Connected!'); - - connection.send({ - message: this.state.own_pub_key, - nick: this.props.ur_nick, - }); - - connection.onMessage(this.onMessage); - connection.onClose(() => { - console.log('Socket is closed. Reconnect will be attempted'); - this.setState({ connected: false }); - }); - connection.onError(() => { - console.error('Socket encountered error: Closing socket'); - this.setState({ connected: false }); - }); - - this.setState({ connected: true, connection }); - }); - } - - componentDidUpdate() { - // Only fire the scroll and audio when the reason for Update is a new message - if (this.state.scrollNow) { - const audio = new Audio(`/static/assets/sounds/chat-open.mp3`); - audio.play(); - this.scrollToBottom(); - this.setState({ scrollNow: false }); - } - } - - onMessage = (message) => { - const dataFromServer = JSON.parse(message.data); - console.log('Got reply!', dataFromServer.type); - console.log('PGP message index', dataFromServer.index, ' latestIndex ', this.state.latestIndex); - if (dataFromServer) { - console.log(dataFromServer); - this.setState({ peer_connected: dataFromServer.peer_connected }); - - // If we receive our own key on a message - if (dataFromServer.message == this.state.own_pub_key) { - console.log('OWN PUB KEY RECEIVED!!'); - } - - // If we receive a public key other than ours (our peer key!) - if ( - dataFromServer.message.substring(0, 36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` && - dataFromServer.message != this.state.own_pub_key - ) { - if (dataFromServer.message == this.state.peer_pub_key) { - console.log('PEER HAS RECONNECTED USING HIS PREVIOUSLY KNOWN PUBKEY'); - } else if ( - (dataFromServer.message != this.state.peer_pub_key) & - (this.state.peer_pub_key != null) - ) { - console.log('PEER PUBKEY HAS CHANGED'); - } - console.log('PEER PUBKEY RECEIVED!!'); - this.setState({ peer_pub_key: dataFromServer.message }); - - // After receiving the peer pubkey we ask the server for the historic messages if any - this.state.connection.send({ - message: `-----SERVE HISTORY-----`, - nick: this.props.ur_nick, - }); - } - - // If we receive an encrypted message - else if ( - dataFromServer.message.substring(0, 27) == `-----BEGIN PGP MESSAGE-----` && - dataFromServer.index > this.state.latestIndex - ) { - decryptMessage( - dataFromServer.message.split('\\').join('\n'), - dataFromServer.user_nick == this.props.ur_nick - ? this.state.own_pub_key - : this.state.peer_pub_key, - this.state.own_enc_priv_key, - this.state.token, - ).then((decryptedData) => - this.setState((state) => ({ - scrollNow: true, - waitingEcho: - this.state.waitingEcho == true - ? decryptedData.decryptedMessage != this.state.lastSent - : false, - lastSent: - decryptedData.decryptedMessage == this.state.lastSent - ? '----BLANK----' - : this.state.lastSent, - latestIndex: - dataFromServer.index > this.state.latestIndex - ? dataFromServer.index - : this.state.latestIndex, - messages: [ - ...state.messages, - { - index: dataFromServer.index, - encryptedMessage: dataFromServer.message.split('\\').join('\n'), - plainTextMessage: decryptedData.decryptedMessage, - validSignature: decryptedData.validSignature, - userNick: dataFromServer.user_nick, - time: dataFromServer.time, - }, - ].sort(function (a, b) { - // order the message array by their index (increasing) - return a.index - b.index; - }), - })), - ); - } - - // We allow plaintext communication. The user must write # to start - // If we receive an plaintext message - else if (dataFromServer.message.substring(0, 1) == '#') { - console.log('Got plaintext message', dataFromServer.message); - this.setState((state) => ({ - scrollNow: true, - messages: [ - ...state.messages, - { - index: this.state.latestIndex + 0.001, - encryptedMessage: dataFromServer.message, - plainTextMessage: dataFromServer.message, - validSignature: false, - userNick: dataFromServer.user_nick, - time: new Date().toString(), - }, - ], - })); - } - } - }; - - scrollToBottom = () => { - this.messagesEnd.scrollIntoView({ behavior: 'smooth' }); - }; - - onButtonClicked = (e) => { - // If input string contains token. Do not set message - if (this.state.value.indexOf(this.state.token) !== -1) { - alert( - `Aye! You just sent your own robot token to your peer in chat, that's a catastrophic idea! So bad your message was blocked.`, - ); - this.setState({ value: '' }); - } - - // If input string contains '#' send unencrypted and unlogged message - else if (this.state.value.substring(0, 1) == '#') { - this.state.connection.send({ - message: this.state.value, - nick: this.props.ur_nick, - }); - this.setState({ value: '' }); - } - - // Else if message is not empty send message - else if (this.state.value != '') { - this.setState({ value: '', waitingEcho: true, lastSent: this.state.value }); - encryptMessage( - this.state.value, - this.state.own_pub_key, - this.state.peer_pub_key, - this.state.own_enc_priv_key, - this.state.token, - ).then( - (encryptedMessage) => - console.log('Sending Encrypted MESSAGE', encryptedMessage) & - this.state.connection.send({ - message: encryptedMessage.split('\n').join('\\'), - nick: this.props.ur_nick, - }), - ); - } - e.preventDefault(); - }; - - createJsonFile = () => { - return { - credentials: { - own_public_key: this.state.own_pub_key, - peer_public_key: this.state.peer_pub_key, - encrypted_private_key: this.state.own_enc_priv_key, - passphrase: this.state.token, - }, - messages: this.state.messages, - }; - }; - - messageCard = (props) => { - const { t } = this.props; - return ( - - - } - style={{ backgroundColor: props.cardColor }} - title={ - -
-
- {props.message.userNick} - {props.message.validSignature ? ( - - ) : ( - - )} -
-
- - this.setState((prevState) => { - const newShowPGP = [...prevState.showPGP]; - newShowPGP[props.index] = !newShowPGP[props.index]; - return { showPGP: newShowPGP }; - }) - } - > - - -
-
- - - systemClient.copyToClipboard( - 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, - }, - }} - /> -
- ); - }; - - render() { - const { t } = this.props; - return ( - - - - - - - {t('You') + ': '} - {this.state.connected ? t('connected') : t('disconnected')} - - - - - - - - {t('Peer') + ': '} - {this.state.peer_connected ? t('connected') : t('disconnected')} - - - - - -
- - {this.state.messages.map((message, index) => ( -
  • - {message.userNick == this.props.ur_nick ? ( - - ) : ( - - )} -
  • - ))} -
    { - this.messagesEnd = el; - }} - >
    -
    -
    - - - { - this.setState({ value: e.target.value }); - this.value = this.state.value; - }} - sx={{ width: 219 }} - /> - - - - - -
    -
    - -
    - - - this.setState({ audit: false })} - orderId={Number(this.props.orderId)} - messages={this.state.messages} - own_pub_key={this.state.own_pub_key} - own_enc_priv_key={this.state.own_enc_priv_key} - peer_pub_key={this.state.peer_pub_key ? this.state.peer_pub_key : 'Not received yet'} - passphrase={this.state.token} - onClickBack={() => this.setState({ audit: false })} - /> - - - - - - - - - - - - - - - ); - } -} - -export default withTranslation()(Chat); diff --git a/frontend/src/components/TradeBox/EncryptedChat/index.tsx b/frontend/src/components/TradeBox/EncryptedChat/index.tsx index bc55c3ad..c1325dcc 100644 --- a/frontend/src/components/TradeBox/EncryptedChat/index.tsx +++ b/frontend/src/components/TradeBox/EncryptedChat/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, @@ -12,8 +12,8 @@ import { Paper, Typography, } from '@mui/material'; -import { encryptMessage, decryptMessage } from '../../../utils/pgp'; -import { saveAsJson } from '../../../utils/saveFile'; +import { encryptMessage, decryptMessage } from '../../../pgp'; +import { saveAsJson } from '../../../utils'; import { AuditPGPDialog } from '../../Dialogs'; import RobotAvatar from '../../RobotAvatar'; import { systemClient } from '../../../services/System'; @@ -520,4 +520,4 @@ const EncryptedChat: React.FC = ({ orderId, userNick }: Props): JSX.Eleme ); }; -export default EncryptedChat; +export default EncryptedChat; \ No newline at end of file diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index d3dc08ae..cbabd236 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -149,7 +149,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 - versionName "0.2.2-alpha" + versionName "0.2.3-alpha" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/mobile/package.json b/mobile/package.json index ab16196e..1f9c5c75 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -1,6 +1,6 @@ { "name": "robosats", - "version": "0.2.2", + "version": "0.2.3", "private": true, "scripts": { "android": "react-native run-android", diff --git a/version.json b/version.json index a80d9c24..a5259ef9 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { "major": 0, "minor": 2, - "patch": 2 + "patch": 3 }