Merge pull request #92 from status-im/chat-messages

This commit is contained in:
Franck Royer 2021-10-22 14:11:33 +11:00 committed by GitHub
commit 1f71792d56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 11 deletions

View File

@ -4,7 +4,7 @@ import { Waku } from "js-waku";
import { Community } from "./community"; import { Community } from "./community";
import { CommunityDescription } from "./wire/community_description"; import { CommunityDescription } from "./wire/community_description";
describe("Community live data", () => { describe("Community [live data]", () => {
before(function () { before(function () {
if (process.env.CI) { if (process.env.CI) {
// Skip live data test in CI // Skip live data test in CI

View File

@ -11,4 +11,14 @@ describe("Encryption", () => {
"c49ad65ebf2a7b7253bf400e3d27719362a91b2c9b9f54d50a69117021666c33" "c49ad65ebf2a7b7253bf400e3d27719362a91b2c9b9f54d50a69117021666c33"
); );
}); });
it("Generate symmetric key from password for chat", async function () {
const str =
"0x02dcec6041fb999d65f1d33363e08c93d3c1f6f0fbbb26add383e2cf46c2b921f41dc14fd8-9a8b-4df5-a358-2c3067be5439";
const symKey = await createSymKeyFromPassword(str);
expect(Buffer.from(symKey).toString("hex")).to.eq(
"76ff5bf0a74a8e724367c7fc003f066d477641f468768a8da2817addf5c2ce76"
);
});
}); });

View File

@ -1,6 +1,7 @@
import { expect } from "chai"; import { expect } from "chai";
import debug from "debug"; import debug from "debug";
import { Community } from "./community";
import { Identity } from "./identity"; import { Identity } from "./identity";
import { Messenger } from "./messenger"; import { Messenger } from "./messenger";
import { bufToHex } from "./utils"; import { bufToHex } from "./utils";
@ -118,3 +119,68 @@ describe("Messenger", () => {
await messengerBob.stop(); await messengerBob.stop();
}); });
}); });
describe("Messenger [live data]", () => {
before(function () {
if (process.env.CI) {
// Skip live data test in CI
this.skip();
}
});
let messenger: Messenger;
let identity: Identity;
beforeEach(async function () {
this.timeout(20_000);
dbg("Generate keys");
identity = Identity.generate();
dbg("Create messengers");
messenger = await Messenger.create(identity, { bootstrap: true });
dbg("Wait to be connected to a peer");
await messenger.waku.waitForConnectedPeer();
dbg("Messengers ready");
});
it("Receive public chat messages", async function () {
this.timeout(20_000);
const community = await Community.instantiateCommunity(
"0x0262c65c881f5a9f79343a26faaa02aad3af7c533d9445fb1939ed11b8bf4d2abd",
messenger.waku
);
await messenger.joinChats(community.chats.values());
const startTime = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const endTime = new Date();
const chat = Array.from(community.chats.values()).find(
(chat) => chat.communityChat?.identity?.displayName === "foobar"
);
if (!chat) throw "Could not find foobar chat";
console.log(chat);
await messenger.retrievePreviousMessages(
chat.id,
startTime,
endTime,
(metadata) => {
metadata.forEach((m) => {
console.log("Message", m.chatMessage?.text);
});
}
);
});
afterEach(async function () {
this.timeout(5000);
await messenger.stop();
});
});

View File

@ -15,7 +15,11 @@ export class Messenger {
chatsById: Map<string, Chat>; chatsById: Map<string, Chat>;
observers: { observers: {
[chatId: string]: Set< [chatId: string]: Set<
(message: ApplicationMetadataMessage, timestamp: Date) => void (
message: ApplicationMetadataMessage,
timestamp: Date,
chatId: string
) => void
>; >;
}; };
identity: Identity; identity: Identity;
@ -49,6 +53,19 @@ export class Messenger {
await this.joinChat(chat); await this.joinChat(chat);
} }
/**
* Joins several of public chats.
*
* Use `addListener` to get messages received on these chats.
*/
public async joinChats(chats: Iterable<Chat>): Promise<void> {
await Promise.all(
Array.from(chats).map((chat) => {
return this.joinChat(chat);
})
);
}
/** /**
* Joins a public chat. * Joins a public chat.
* *
@ -110,18 +127,30 @@ export class Messenger {
* @throws string If the chat has not been joined first using [joinChat]. * @throws string If the chat has not been joined first using [joinChat].
*/ */
public addObserver( public addObserver(
observer: (message: ApplicationMetadataMessage, timestamp: Date) => void, observer: (
chatId: string message: ApplicationMetadataMessage,
timestamp: Date,
chatId: string
) => void,
chatId: string | string[]
): void { ): void {
// Not sure this is the best design here. Maybe `addObserver` and `joinChat` should be merged. let chats = [];
if (!this.chatsById.has(chatId)) if (typeof chatId === "string") {
throw "Cannot add observer on a chat that is not joined."; chats.push(chatId);
if (!this.observers[chatId]) { } else {
this.observers[chatId] = new Set(); chats = [...chatId];
} }
this.observers[chatId].add(observer); chats.forEach((id) => {
if (!this.chatsById.has(id))
throw "Cannot add observer on a chat that is not joined.";
if (!this.observers[id]) {
this.observers[id] = new Set();
}
this.observers[id].add(observer);
});
} }
/** /**
@ -211,7 +240,7 @@ export class Messenger {
if (this.observers[chat.id]) { if (this.observers[chat.id]) {
this.observers[chat.id].forEach((observer) => { this.observers[chat.id].forEach((observer) => {
observer(message, timestamp); observer(message, timestamp, chat.id);
}); });
} }
} }