Add encryption for chat groups
This commit is contained in:
parent
bbf5cc6b00
commit
8f702928bc
|
@ -44,6 +44,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"ecies-geth": "^1.5.3",
|
||||
"js-sha3": "^0.8.0",
|
||||
"js-waku": "^0.12.0",
|
||||
"protobufjs": "^6.11.2",
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
import { ChatMessage } from "./chat_message";
|
||||
import { chatIdToContentTopic } from "./contentTopic";
|
||||
import { createSymKeyFromPassword } from "./encryption";
|
||||
|
||||
/**
|
||||
* Represent a chat room. Only public chats are currently supported.
|
||||
*/
|
||||
export class Chat {
|
||||
private lastClockValue?: number;
|
||||
private lastMessage?: ChatMessage;
|
||||
public id: string;
|
||||
|
||||
constructor(id: string) {
|
||||
this.id = id;
|
||||
private constructor(public id: string, public symKey: Uint8Array) {}
|
||||
|
||||
/**
|
||||
* Create a public chat room.
|
||||
*/
|
||||
public static async create(id: string) {
|
||||
const symKey = await createSymKeyFromPassword(id);
|
||||
|
||||
return new Chat(id, symKey);
|
||||
}
|
||||
|
||||
public get contentTopic(): string {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { kdf } from "ecies-geth";
|
||||
|
||||
const AESKeyLength = 32; // bytes
|
||||
|
||||
export async function createSymKeyFromPassword(
|
||||
password: string
|
||||
): Promise<Uint8Array> {
|
||||
return kdf(Buffer.from(password, "utf-8"), AESKeyLength);
|
||||
}
|
|
@ -47,8 +47,8 @@ describe("Messenger", () => {
|
|||
it("Sends & Receive message in public chat", async function () {
|
||||
this.timeout(10_000);
|
||||
|
||||
messengerAlice.joinChat(testChatId);
|
||||
messengerBob.joinChat(testChatId);
|
||||
await messengerAlice.joinChat(testChatId);
|
||||
await messengerBob.joinChat(testChatId);
|
||||
|
||||
const text = "This is a message.";
|
||||
|
||||
|
|
|
@ -39,10 +39,12 @@ export class Messenger {
|
|||
*
|
||||
* Use `addListener` to get messages received on this chat.
|
||||
*/
|
||||
public joinChat(chatId: string) {
|
||||
public async joinChat(chatId: string) {
|
||||
if (this.chatsById.has(chatId)) throw "Chat already joined";
|
||||
|
||||
const chat = new Chat(chatId);
|
||||
const chat = await Chat.create(chatId);
|
||||
|
||||
this.waku.relay.addDecryptionKey(chat.symKey);
|
||||
|
||||
this.waku.relay.addObserver(
|
||||
(wakuMessage: WakuMessage) => {
|
||||
|
@ -72,7 +74,7 @@ export class Messenger {
|
|||
*/
|
||||
public async sendMessage(text: string, chatId: string): Promise<void> {
|
||||
const chat = this.chatsById.get(chatId);
|
||||
if (!chat) throw `Chat not joined: ${chatId}`;
|
||||
if (!chat) throw `Failed to send message, chat not joined: ${chatId}`;
|
||||
|
||||
const chatMessage = chat.createMessage(text);
|
||||
|
||||
|
@ -82,10 +84,11 @@ export class Messenger {
|
|||
this.identity
|
||||
);
|
||||
|
||||
// TODO: Use version 1 with signature
|
||||
// TODO: Add signature
|
||||
const wakuMessage = await WakuMessage.fromBytes(
|
||||
appMetadataMessage.encode(),
|
||||
chat.contentTopic
|
||||
chat.contentTopic,
|
||||
{ symKey: chat.symKey }
|
||||
);
|
||||
|
||||
await this.waku.relay.send(wakuMessage);
|
||||
|
|
|
@ -1734,7 +1734,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ecies-geth@npm:^1.5.2":
|
||||
"ecies-geth@npm:^1.5.2, ecies-geth@npm:^1.5.3":
|
||||
version: 1.5.3
|
||||
resolution: "ecies-geth@npm:1.5.3"
|
||||
dependencies:
|
||||
|
@ -5635,6 +5635,7 @@ fsevents@~2.3.2:
|
|||
"@typescript-eslint/parser": ^4.31.1
|
||||
buffer: ^6.0.3
|
||||
chai: ^4.3.4
|
||||
ecies-geth: ^1.5.3
|
||||
eslint: ^7.32.0
|
||||
eslint-config-prettier: ^8.3.0
|
||||
eslint-import-resolver-node: ^0.3.6
|
||||
|
|
Loading…
Reference in New Issue