mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-27 01:53:06 +00:00
Waku Messages are considered invalid if the content topic is undefined or an empty string. Avoid user error by throwing.
167 lines
5.7 KiB
TypeScript
167 lines
5.7 KiB
TypeScript
import { IProtoMessage } from "@waku/interfaces";
|
|
import { expect } from "chai";
|
|
import fc from "fast-check";
|
|
|
|
import { getPublicKey } from "./crypto/index.js";
|
|
import { createDecoder, createEncoder } from "./ecies.js";
|
|
|
|
describe("Ecies Encryption", function () {
|
|
it("Round trip binary encryption [ecies, no signature]", async function () {
|
|
await fc.assert(
|
|
fc.asyncProperty(
|
|
fc.string({ minLength: 1 }),
|
|
fc.string({ minLength: 1 }),
|
|
fc.uint8Array({ minLength: 1 }),
|
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
|
async (pubSubTopic, contentTopic, payload, privateKey) => {
|
|
const publicKey = getPublicKey(privateKey);
|
|
|
|
const encoder = createEncoder({
|
|
contentTopic,
|
|
publicKey,
|
|
});
|
|
const bytes = await encoder.toWire({ payload });
|
|
|
|
const decoder = createDecoder(contentTopic, privateKey);
|
|
const protoResult = await decoder.fromWireToProtoObj(bytes!);
|
|
if (!protoResult) throw "Failed to proto decode";
|
|
const result = await decoder.fromProtoObj(pubSubTopic, protoResult);
|
|
if (!result) throw "Failed to decode";
|
|
|
|
expect(result.contentTopic).to.equal(contentTopic);
|
|
expect(result.pubSubTopic).to.equal(pubSubTopic);
|
|
expect(result.version).to.equal(1);
|
|
expect(result?.payload).to.deep.equal(payload);
|
|
expect(result.signature).to.be.undefined;
|
|
expect(result.signaturePublicKey).to.be.undefined;
|
|
}
|
|
)
|
|
);
|
|
});
|
|
|
|
it("R trip binary encryption [ecies, signature]", async function () {
|
|
this.timeout(4000);
|
|
|
|
await fc.assert(
|
|
fc.asyncProperty(
|
|
fc.string({ minLength: 1 }),
|
|
fc.string({ minLength: 1 }),
|
|
fc.uint8Array({ minLength: 1 }),
|
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
|
async (
|
|
pubSubTopic,
|
|
contentTopic,
|
|
payload,
|
|
alicePrivateKey,
|
|
bobPrivateKey
|
|
) => {
|
|
const alicePublicKey = getPublicKey(alicePrivateKey);
|
|
const bobPublicKey = getPublicKey(bobPrivateKey);
|
|
|
|
const encoder = createEncoder({
|
|
contentTopic,
|
|
publicKey: bobPublicKey,
|
|
sigPrivKey: alicePrivateKey,
|
|
});
|
|
const bytes = await encoder.toWire({ payload });
|
|
|
|
const decoder = createDecoder(contentTopic, bobPrivateKey);
|
|
const protoResult = await decoder.fromWireToProtoObj(bytes!);
|
|
if (!protoResult) throw "Failed to proto decode";
|
|
const result = await decoder.fromProtoObj(pubSubTopic, protoResult);
|
|
if (!result) throw "Failed to decode";
|
|
|
|
expect(result.contentTopic).to.equal(contentTopic);
|
|
expect(result.pubSubTopic).to.equal(pubSubTopic);
|
|
expect(result.version).to.equal(1);
|
|
expect(result?.payload).to.deep.equal(payload);
|
|
expect(result.signature).to.not.be.undefined;
|
|
expect(result.signaturePublicKey).to.deep.eq(alicePublicKey);
|
|
}
|
|
)
|
|
);
|
|
});
|
|
|
|
it("Check meta is set [ecies]", async function () {
|
|
await fc.assert(
|
|
fc.asyncProperty(
|
|
fc.string({ minLength: 1 }),
|
|
fc.string({ minLength: 1 }),
|
|
fc.uint8Array({ minLength: 1 }),
|
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
|
async (pubSubTopic, contentTopic, payload, privateKey) => {
|
|
const publicKey = getPublicKey(privateKey);
|
|
const metaSetter = (
|
|
msg: IProtoMessage & { meta: undefined }
|
|
): Uint8Array => {
|
|
const buffer = new ArrayBuffer(4);
|
|
const view = new DataView(buffer);
|
|
view.setUint32(0, msg.payload.length, false);
|
|
return new Uint8Array(buffer);
|
|
};
|
|
|
|
const encoder = createEncoder({
|
|
contentTopic,
|
|
publicKey,
|
|
metaSetter,
|
|
});
|
|
const bytes = await encoder.toWire({ payload });
|
|
|
|
const decoder = createDecoder(contentTopic, privateKey);
|
|
const protoResult = await decoder.fromWireToProtoObj(bytes!);
|
|
if (!protoResult) throw "Failed to proto decode";
|
|
const result = await decoder.fromProtoObj(pubSubTopic, protoResult);
|
|
if (!result) throw "Failed to decode";
|
|
|
|
const expectedMeta = metaSetter({
|
|
payload: protoResult.payload,
|
|
timestamp: undefined,
|
|
contentTopic: "",
|
|
ephemeral: undefined,
|
|
meta: undefined,
|
|
rateLimitProof: undefined,
|
|
version: undefined,
|
|
});
|
|
|
|
expect(result.meta).to.deep.equal(expectedMeta);
|
|
}
|
|
)
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Ensures content topic is defined", () => {
|
|
it("Encoder throws on undefined content topic", () => {
|
|
const wrapper = function (): void {
|
|
createEncoder({
|
|
contentTopic: undefined as unknown as string,
|
|
publicKey: new Uint8Array(),
|
|
});
|
|
};
|
|
|
|
expect(wrapper).to.throw("Content topic must be specified");
|
|
});
|
|
it("Encoder throws on empty string content topic", () => {
|
|
const wrapper = function (): void {
|
|
createEncoder({ contentTopic: "", publicKey: new Uint8Array() });
|
|
};
|
|
|
|
expect(wrapper).to.throw("Content topic must be specified");
|
|
});
|
|
it("Decoder throws on undefined content topic", () => {
|
|
const wrapper = function (): void {
|
|
createDecoder(undefined as unknown as string, new Uint8Array());
|
|
};
|
|
|
|
expect(wrapper).to.throw("Content topic must be specified");
|
|
});
|
|
it("Decoder throws on empty string content topic", () => {
|
|
const wrapper = function (): void {
|
|
createDecoder("", new Uint8Array());
|
|
};
|
|
|
|
expect(wrapper).to.throw("Content topic must be specified");
|
|
});
|
|
});
|