mirror of https://github.com/waku-org/js-waku.git
Enable decryption of messages retrieve via `WakuStore.queryHistory`
This commit is contained in:
parent
d68ee3fb74
commit
0e9c482a19
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- New `lib/utils` module for easy, dependency-less hex/bytes conversions.
|
||||
- New `peers` and `randomPeer` methods on `WakuStore` and `WakuLightPush` to have a better idea of available peers;
|
||||
Note that it does not check whether Waku node is currently connected to said peers.
|
||||
- Enable passing decryption private keys to `WakuStore.queryHistory`.
|
||||
|
||||
### Changed
|
||||
- **Breaking**: Auto select peer if none provided for store and light push protocols.
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
import { expect } from 'chai';
|
||||
import debug from 'debug';
|
||||
import TCP from 'libp2p-tcp';
|
||||
|
||||
import { makeLogFileName, NimWaku, NOISE_KEY_1 } from '../../test_utils';
|
||||
import {
|
||||
makeLogFileName,
|
||||
NimWaku,
|
||||
NOISE_KEY_1,
|
||||
NOISE_KEY_2,
|
||||
} from '../../test_utils';
|
||||
import { delay } from '../delay';
|
||||
import { Waku } from '../waku';
|
||||
import { DefaultContentTopic, WakuMessage } from '../waku_message';
|
||||
import { generatePrivateKey, getPublicKey } from '../waku_message/version_1';
|
||||
|
||||
import { Direction } from './history_rpc';
|
||||
|
||||
const dbg = debug('waku:test:store');
|
||||
|
||||
describe('Waku Store', () => {
|
||||
let waku: Waku;
|
||||
let nimWaku: NimWaku;
|
||||
|
@ -133,4 +143,87 @@ describe('Waku Store', () => {
|
|||
});
|
||||
expect(result).to.not.eq(-1);
|
||||
});
|
||||
|
||||
it('Retrieves history with asymmetric encrypted messages', async function () {
|
||||
this.timeout(10_000);
|
||||
|
||||
nimWaku = new NimWaku(makeLogFileName(this));
|
||||
await nimWaku.start({ persistMessages: true, lightpush: true });
|
||||
|
||||
const encryptedMessageText = 'This message is encrypted for me';
|
||||
const clearMessageText =
|
||||
'This is a clear text message for everyone to read';
|
||||
const otherEncMessageText =
|
||||
'This message is not for and I must not be able to read it';
|
||||
|
||||
const privateKey = generatePrivateKey();
|
||||
const publicKey = getPublicKey(privateKey);
|
||||
|
||||
const [encryptedMessage, clearMessage, otherEncMessage] = await Promise.all(
|
||||
[
|
||||
WakuMessage.fromUtf8String(encryptedMessageText, {
|
||||
encPublicKey: publicKey,
|
||||
}),
|
||||
WakuMessage.fromUtf8String(clearMessageText),
|
||||
WakuMessage.fromUtf8String(otherEncMessageText, {
|
||||
encPublicKey: getPublicKey(generatePrivateKey()),
|
||||
}),
|
||||
]
|
||||
);
|
||||
|
||||
dbg('Messages have been encrypted');
|
||||
|
||||
const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([
|
||||
Waku.create({
|
||||
staticNoiseKey: NOISE_KEY_1,
|
||||
libp2p: { modules: { transport: [TCP] } },
|
||||
}),
|
||||
Waku.create({
|
||||
staticNoiseKey: NOISE_KEY_2,
|
||||
libp2p: { modules: { transport: [TCP] } },
|
||||
}),
|
||||
nimWaku.getMultiaddrWithId(),
|
||||
]);
|
||||
|
||||
dbg('Waku nodes created');
|
||||
|
||||
await Promise.all([
|
||||
waku1.dial(nimWakuMultiaddr),
|
||||
waku2.dial(nimWakuMultiaddr),
|
||||
]);
|
||||
|
||||
dbg('Waku nodes connected to nim Waku');
|
||||
|
||||
let lightPushPeers = waku1.lightPush.peers;
|
||||
while (lightPushPeers.length == 0) {
|
||||
await delay(100);
|
||||
lightPushPeers = waku1.lightPush.peers;
|
||||
}
|
||||
|
||||
dbg('Sending messages using light push');
|
||||
await Promise.all([
|
||||
await waku1.lightPush.push(encryptedMessage),
|
||||
waku1.lightPush.push(otherEncMessage),
|
||||
waku1.lightPush.push(clearMessage),
|
||||
]);
|
||||
|
||||
let storePeers = waku2.store.peers;
|
||||
while (storePeers.length == 0) {
|
||||
await delay(100);
|
||||
storePeers = waku2.store.peers;
|
||||
}
|
||||
|
||||
dbg('Retrieve messages from store');
|
||||
const messages = await waku2.store.queryHistory({
|
||||
contentTopics: [],
|
||||
decryptionPrivateKeys: [privateKey],
|
||||
});
|
||||
|
||||
expect(messages?.length).eq(2);
|
||||
if (!messages) throw 'Length was tested';
|
||||
expect(messages[0].payloadAsUtf8).to.eq(clearMessageText);
|
||||
expect(messages[1].payloadAsUtf8).to.eq(encryptedMessageText);
|
||||
|
||||
await Promise.all([waku1.stop(), waku2.stop()]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import debug from 'debug';
|
||||
import concat from 'it-concat';
|
||||
import lp from 'it-length-prefixed';
|
||||
import pipe from 'it-pipe';
|
||||
|
@ -11,6 +12,8 @@ import { DefaultPubsubTopic } from '../waku_relay';
|
|||
|
||||
import { Direction, HistoryRPC } from './history_rpc';
|
||||
|
||||
const dbg = debug('waku:store');
|
||||
|
||||
export const StoreCodec = '/vac/waku/store/2.0.0-beta3';
|
||||
|
||||
export { Direction };
|
||||
|
@ -34,6 +37,7 @@ export interface QueryOptions {
|
|||
direction?: Direction;
|
||||
pageSize?: number;
|
||||
callback?: (messages: WakuMessage[]) => void;
|
||||
decryptionPrivateKeys?: Uint8Array[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +75,7 @@ export class WakuStore {
|
|||
},
|
||||
options
|
||||
);
|
||||
dbg('Querying history with the following options', options);
|
||||
|
||||
let peer;
|
||||
if (opts.peerId) {
|
||||
|
@ -115,10 +120,17 @@ export class WakuStore {
|
|||
return messages;
|
||||
}
|
||||
|
||||
dbg(
|
||||
`${response.messages.length} messages retrieved for pubsub topic ${opts.pubsubTopic}`
|
||||
);
|
||||
|
||||
const pageMessages: WakuMessage[] = [];
|
||||
await Promise.all(
|
||||
response.messages.map(async (protoMsg) => {
|
||||
const msg = await WakuMessage.decodeProto(protoMsg);
|
||||
const msg = await WakuMessage.decodeProto(
|
||||
protoMsg,
|
||||
opts.decryptionPrivateKeys
|
||||
);
|
||||
|
||||
if (msg) {
|
||||
messages.push(msg);
|
||||
|
|
Loading…
Reference in New Issue