mirror of
https://github.com/RoboSats/robosats.git
synced 2025-07-18 00:33:15 +00:00
Serve PGP messages after reconnect
This commit is contained in:
@ -25,12 +25,13 @@ class MessageAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
|
|||||||
list_display = (
|
list_display = (
|
||||||
"id",
|
"id",
|
||||||
"chatroom_link",
|
"chatroom_link",
|
||||||
|
"index",
|
||||||
"order_link",
|
"order_link",
|
||||||
"sender_link",
|
"sender_link",
|
||||||
"receiver_link",
|
"receiver_link",
|
||||||
"created_at",
|
"created_at",
|
||||||
)
|
)
|
||||||
change_links = ["chatroom","order","sender","receiver"]
|
change_links = ["chatroom","order","sender","receiver"]
|
||||||
search_fields = ["id","order"]
|
search_fields = ["id","index"]
|
||||||
ordering = ("-index", )
|
ordering = ["-chatroom_id","-index"]
|
||||||
list_filter = ("chatroom",)
|
list_filter = ("chatroom",)
|
@ -47,28 +47,33 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
def save_new_message(self):
|
def save_new_PGP_message(self, PGP_message):
|
||||||
'''Creates a Message object'''
|
'''Creates a Message object'''
|
||||||
|
|
||||||
order = Order.objects.get(id=self.order_id)
|
order = Order.objects.get(id=self.order_id)
|
||||||
chatroom = ChatRoom.objects.get(order=order)
|
chatroom = ChatRoom.objects.get(order=order)
|
||||||
|
|
||||||
index = 0
|
try:
|
||||||
last_message = Message.objects.filter(order=order).latest()
|
last_message = Message.objects.filter(order=order).latest()
|
||||||
if last_message:
|
|
||||||
index = last_message.index + 1
|
index = last_message.index + 1
|
||||||
|
except:
|
||||||
|
index = 1
|
||||||
|
|
||||||
sender = self.scope["user"]
|
sender = self.scope["user"]
|
||||||
|
if order.taker == sender:
|
||||||
|
receiver = order.maker
|
||||||
|
elif order.maker == sender:
|
||||||
|
receiver = order.taker
|
||||||
|
|
||||||
Message.objects.create(
|
msg_obj = Message.objects.create(
|
||||||
order=order,
|
order=order,
|
||||||
chatroom=chatroom,
|
chatroom=chatroom,
|
||||||
index=index,
|
index=index,
|
||||||
sender=sender,
|
sender=sender,
|
||||||
PGP_message=self.PGP_message,
|
receiver=receiver,
|
||||||
|
PGP_message=PGP_message,
|
||||||
)
|
)
|
||||||
|
return msg_obj
|
||||||
return None
|
|
||||||
|
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
def save_disconnect_user(self):
|
def save_disconnect_user(self):
|
||||||
@ -103,6 +108,36 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
|||||||
if chatroom.taker == self.user:
|
if chatroom.taker == self.user:
|
||||||
return chatroom.maker_connected
|
return chatroom.maker_connected
|
||||||
|
|
||||||
|
@database_sync_to_async
|
||||||
|
def get_peer_PGP_public_key(self):
|
||||||
|
'''Returns peer PGP public key'''
|
||||||
|
|
||||||
|
order = Order.objects.get(id=self.order_id)
|
||||||
|
|
||||||
|
if order.maker == self.user:
|
||||||
|
return order.taker.profile.public_key
|
||||||
|
|
||||||
|
if order.taker == self.user:
|
||||||
|
return order.maker.profile.public_key
|
||||||
|
|
||||||
|
@database_sync_to_async
|
||||||
|
def get_all_PGP_messages(self):
|
||||||
|
'''Returns all PGP messages'''
|
||||||
|
|
||||||
|
order = Order.objects.get(id=self.order_id)
|
||||||
|
messages = Message.objects.filter(order=order)
|
||||||
|
|
||||||
|
msgs = []
|
||||||
|
for message in messages:
|
||||||
|
msgs.append({
|
||||||
|
"index": message.index,
|
||||||
|
"time": str(message.created_at),
|
||||||
|
"message": message.PGP_message,
|
||||||
|
"nick": str(message.sender),
|
||||||
|
})
|
||||||
|
|
||||||
|
return msgs
|
||||||
|
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
self.order_id = self.scope["url_route"]["kwargs"]["order_id"]
|
self.order_id = self.scope["url_route"]["kwargs"]["order_id"]
|
||||||
self.room_group_name = f"chat_order_{self.order_id}"
|
self.room_group_name = f"chat_order_{self.order_id}"
|
||||||
@ -118,6 +153,33 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
|||||||
|
|
||||||
await self.accept()
|
await self.accept()
|
||||||
|
|
||||||
|
# Send peer PGP public keys
|
||||||
|
peer_public_key = await self.get_peer_PGP_public_key()
|
||||||
|
await self.channel_layer.group_send(
|
||||||
|
self.room_group_name,
|
||||||
|
{
|
||||||
|
"type": "chatroom_message",
|
||||||
|
"message": peer_public_key,
|
||||||
|
"nick": self.scope["user"].username,
|
||||||
|
"peer_connected": None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# If there is any stored message, serve them.
|
||||||
|
msgs = await self.get_all_PGP_messages()
|
||||||
|
for msg in msgs:
|
||||||
|
await self.channel_layer.group_send(
|
||||||
|
self.room_group_name,
|
||||||
|
{
|
||||||
|
"type": "PGP_message",
|
||||||
|
"index": msg['index'],
|
||||||
|
"time": msg['time'],
|
||||||
|
"message": msg['message'],
|
||||||
|
"nick": msg['nick'],
|
||||||
|
"peer_connected": None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
async def disconnect(self, close_code):
|
async def disconnect(self, close_code):
|
||||||
await self.save_disconnect_user()
|
await self.save_disconnect_user()
|
||||||
await self.channel_layer.group_discard(self.room_group_name,
|
await self.channel_layer.group_discard(self.room_group_name,
|
||||||
@ -135,13 +197,30 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
|||||||
async def receive(self, text_data):
|
async def receive(self, text_data):
|
||||||
text_data_json = json.loads(text_data)
|
text_data_json = json.loads(text_data)
|
||||||
message = text_data_json["message"]
|
message = text_data_json["message"]
|
||||||
|
peer_connected = await self.is_peer_connected()
|
||||||
|
|
||||||
# Encrypted messages are stored. They are served later when a user reconnects.
|
# Encrypted messages are stored. They are served later when a user reconnects.
|
||||||
if message[0,27] == '-----BEGIN PGP MESSAGE-----':
|
if message[0:27] == '-----BEGIN PGP MESSAGE-----':
|
||||||
self.PGP_message = message
|
# save to database
|
||||||
await self.save_new_message()
|
msg_obj = await self.save_new_PGP_message(message)
|
||||||
|
|
||||||
peer_connected = await self.is_peer_connected()
|
index = msg_obj.index
|
||||||
|
message = msg_obj.PGP_message
|
||||||
|
time = str(msg_obj.created_at)
|
||||||
|
|
||||||
|
await self.channel_layer.group_send(
|
||||||
|
self.room_group_name,
|
||||||
|
{
|
||||||
|
"type": "PGP_message",
|
||||||
|
"index": index,
|
||||||
|
"message": message,
|
||||||
|
"time": time,
|
||||||
|
"nick": self.scope["user"].username,
|
||||||
|
"peer_connected": peer_connected,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
await self.channel_layer.group_send(
|
await self.channel_layer.group_send(
|
||||||
self.room_group_name,
|
self.room_group_name,
|
||||||
{
|
{
|
||||||
@ -161,7 +240,19 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
|||||||
"message": message,
|
"message": message,
|
||||||
"user_nick": nick,
|
"user_nick": nick,
|
||||||
"peer_connected": peer_connected,
|
"peer_connected": peer_connected,
|
||||||
"time":str(timezone.now()),
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
pass
|
async def PGP_message(self, event):
|
||||||
|
message = event["message"]
|
||||||
|
nick = event["nick"]
|
||||||
|
index = event["index"]
|
||||||
|
peer_connected = event["peer_connected"]
|
||||||
|
time = event["time"]
|
||||||
|
|
||||||
|
await self.send(text_data=json.dumps({
|
||||||
|
"index": index,
|
||||||
|
"message": message,
|
||||||
|
"user_nick": nick,
|
||||||
|
"peer_connected": peer_connected,
|
||||||
|
"time":time,
|
||||||
|
}))
|
||||||
|
@ -47,7 +47,10 @@ class ChatRoom(models.Model):
|
|||||||
return f"Chat:{str(self.order.id)}"
|
return f"Chat:{str(self.order.id)}"
|
||||||
|
|
||||||
class Message(models.Model):
|
class Message(models.Model):
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
class Meta:
|
||||||
|
get_latest_by = 'index'
|
||||||
|
|
||||||
|
# id = models.PositiveBigIntegerField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
order = models.ForeignKey(
|
order = models.ForeignKey(
|
||||||
Order,
|
Order,
|
||||||
related_name="message",
|
related_name="message",
|
||||||
@ -67,6 +70,12 @@ class Message(models.Model):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
default=None)
|
default=None)
|
||||||
|
receiver = models.ForeignKey(
|
||||||
|
User,
|
||||||
|
related_name="message_receiver",
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
default=None)
|
||||||
|
|
||||||
PGP_message = models.TextField(max_length=5000,
|
PGP_message = models.TextField(max_length=5000,
|
||||||
null=True,
|
null=True,
|
||||||
@ -76,4 +85,4 @@ class Message(models.Model):
|
|||||||
created_at = models.DateTimeField(default=timezone.now)
|
created_at = models.DateTimeField(default=timezone.now)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Chat:{str(self.order.id)}-Index:{self.order.index}"
|
return f"Chat:{str(self.order.id)} - Idx:{self.index}"
|
||||||
|
@ -34,6 +34,7 @@ class Chat extends Component {
|
|||||||
showPGP: new Array,
|
showPGP: new Array,
|
||||||
waitingEcho: false,
|
waitingEcho: false,
|
||||||
lastSent: '---BLANK---',
|
lastSent: '---BLANK---',
|
||||||
|
latestIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
rws = new ReconnectingWebSocket('ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/');
|
rws = new ReconnectingWebSocket('ws://' + window.location.host + '/ws/chat/' + this.props.orderId + '/');
|
||||||
@ -42,13 +43,13 @@ class Chat extends Component {
|
|||||||
this.rws.addEventListener('open', () => {
|
this.rws.addEventListener('open', () => {
|
||||||
console.log('Connected!');
|
console.log('Connected!');
|
||||||
this.setState({connected: true});
|
this.setState({connected: true});
|
||||||
if ( this.state.peer_pub_key == null){
|
// if ( this.state.peer_pub_key == null){
|
||||||
this.rws.send(JSON.stringify({
|
// this.rws.send(JSON.stringify({
|
||||||
type: "message",
|
// type: "message",
|
||||||
message: "----PLEASE SEND YOUR PUBKEY----",
|
// message: "----PLEASE SEND YOUR PUBKEY----",
|
||||||
nick: this.props.ur_nick,
|
// nick: this.props.ur_nick,
|
||||||
}));
|
// }));
|
||||||
}
|
// }
|
||||||
this.rws.send(JSON.stringify({
|
this.rws.send(JSON.stringify({
|
||||||
type: "message",
|
type: "message",
|
||||||
message: this.state.own_pub_key,
|
message: this.state.own_pub_key,
|
||||||
@ -60,24 +61,24 @@ class Chat extends Component {
|
|||||||
|
|
||||||
const dataFromServer = JSON.parse(message.data);
|
const dataFromServer = JSON.parse(message.data);
|
||||||
console.log('Got reply!', dataFromServer.type);
|
console.log('Got reply!', dataFromServer.type);
|
||||||
|
console.log('PGP message index', dataFromServer.index, ' latestIndex ',this.state.latestIndex);
|
||||||
if (dataFromServer){
|
if (dataFromServer){
|
||||||
console.log(dataFromServer)
|
console.log(dataFromServer)
|
||||||
|
|
||||||
// If we receive our own key on a message
|
// If we receive our own key on a message
|
||||||
if (dataFromServer.message == this.state.own_pub_key){console.log("ECHO OF OWN PUB KEY RECEIVED!!")}
|
if (dataFromServer.message == this.state.own_pub_key){console.log("OWN PUB KEY RECEIVED!!")}
|
||||||
|
|
||||||
// If we receive a request to send our public key
|
// If we receive a request to send our public key
|
||||||
if (dataFromServer.message == `----PLEASE SEND YOUR PUBKEY----`) {
|
// if (dataFromServer.message == `----PLEASE SEND YOUR PUBKEY----`) {
|
||||||
this.rws.send(JSON.stringify({
|
// this.rws.send(JSON.stringify({
|
||||||
type: "message",
|
// type: "message",
|
||||||
message: this.state.own_pub_key,
|
// message: this.state.own_pub_key,
|
||||||
nick: this.props.ur_nick,
|
// nick: this.props.ur_nick,
|
||||||
}));
|
// }));
|
||||||
} else
|
// } else
|
||||||
|
|
||||||
// If we receive a public key other than ours (our peer key!)
|
// 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.substring(0,36) == `-----BEGIN PGP PUBLIC KEY BLOCK-----` && dataFromServer.message != this.state.own_pub_key) {
|
||||||
if (dataFromServer.message == this.state.peer_pub_key){
|
if (dataFromServer.message == this.state.peer_pub_key){
|
||||||
console.log("PEER HAS RECONNECTED USING HIS PREVIOUSLY KNOWN PUBKEY")
|
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){
|
} else if (dataFromServer.message != this.state.peer_pub_key & this.state.peer_pub_key != null){
|
||||||
@ -88,7 +89,8 @@ class Chat extends Component {
|
|||||||
} else
|
} else
|
||||||
|
|
||||||
// If we receive an encrypted message
|
// If we receive an encrypted message
|
||||||
if (dataFromServer.message.substring(0,27) == `-----BEGIN PGP MESSAGE-----`){
|
if (dataFromServer.message.substring(0,27) == `-----BEGIN PGP MESSAGE-----` && dataFromServer.index > this.state.latestIndex){
|
||||||
|
|
||||||
decryptMessage(
|
decryptMessage(
|
||||||
dataFromServer.message.split('\\').join('\n'),
|
dataFromServer.message.split('\\').join('\n'),
|
||||||
dataFromServer.user_nick == this.props.ur_nick ? this.state.own_pub_key : this.state.peer_pub_key,
|
dataFromServer.user_nick == this.props.ur_nick ? this.state.own_pub_key : this.state.peer_pub_key,
|
||||||
@ -99,8 +101,10 @@ class Chat extends Component {
|
|||||||
({
|
({
|
||||||
waitingEcho: this.state.waitingEcho == true ? (decryptedData.decryptedMessage == this.state.lastSent ? false: true ) : false,
|
waitingEcho: this.state.waitingEcho == true ? (decryptedData.decryptedMessage == this.state.lastSent ? false: true ) : false,
|
||||||
lastSent: decryptedData.decryptedMessage == this.state.lastSent ? '----BLANK----': this.state.lastSent,
|
lastSent: decryptedData.decryptedMessage == this.state.lastSent ? '----BLANK----': this.state.lastSent,
|
||||||
|
latestIndex: dataFromServer.index > this.state.latestIndex ? dataFromServer.index : this.state.latestIndex,
|
||||||
messages: [...state.messages,
|
messages: [...state.messages,
|
||||||
{
|
{
|
||||||
|
index: dataFromServer.index,
|
||||||
encryptedMessage: dataFromServer.message.split('\\').join('\n'),
|
encryptedMessage: dataFromServer.message.split('\\').join('\n'),
|
||||||
plainTextMessage: decryptedData.decryptedMessage,
|
plainTextMessage: decryptedData.decryptedMessage,
|
||||||
validSignature: decryptedData.validSignature,
|
validSignature: decryptedData.validSignature,
|
||||||
|
Reference in New Issue
Block a user