mirror of https://github.com/waku-org/js-waku.git
feat: ensure content topic is defined
Waku Messages are considered invalid if the content topic is undefined or an empty string. Avoid user error by throwing.
This commit is contained in:
parent
6abee4880f
commit
bd9d07394f
|
@ -8,8 +8,8 @@ describe("Waku Message version 0", function () {
|
||||||
it("Round trip binary serialization", async function () {
|
it("Round trip binary serialization", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ minLength: 1 }),
|
fc.uint8Array({ minLength: 1 }),
|
||||||
async (contentTopic, pubSubTopic, payload) => {
|
async (contentTopic, pubSubTopic, payload) => {
|
||||||
const encoder = createEncoder({
|
const encoder = createEncoder({
|
||||||
|
@ -37,8 +37,8 @@ describe("Waku Message version 0", function () {
|
||||||
it("Ephemeral field set to true", async function () {
|
it("Ephemeral field set to true", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ minLength: 1 }),
|
fc.uint8Array({ minLength: 1 }),
|
||||||
async (contentTopic, pubSubTopic, payload) => {
|
async (contentTopic, pubSubTopic, payload) => {
|
||||||
const encoder = createEncoder({
|
const encoder = createEncoder({
|
||||||
|
@ -62,8 +62,8 @@ describe("Waku Message version 0", function () {
|
||||||
it("Meta field set when metaSetter is specified", async function () {
|
it("Meta field set when metaSetter is specified", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ minLength: 1 }),
|
fc.uint8Array({ minLength: 1 }),
|
||||||
async (contentTopic, pubSubTopic, payload) => {
|
async (contentTopic, pubSubTopic, payload) => {
|
||||||
// Encode the length of the payload
|
// Encode the length of the payload
|
||||||
|
@ -106,3 +106,34 @@ describe("Waku Message version 0", function () {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Ensures content topic is defined", () => {
|
||||||
|
it("Encoder throws on undefined content topic", () => {
|
||||||
|
const wrapper = function (): void {
|
||||||
|
createEncoder({ contentTopic: undefined as unknown as string });
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(wrapper).to.throw("Content topic must be specified");
|
||||||
|
});
|
||||||
|
it("Encoder throws on empty string content topic", () => {
|
||||||
|
const wrapper = function (): void {
|
||||||
|
createEncoder({ contentTopic: "" });
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(wrapper).to.throw("Content topic must be specified");
|
||||||
|
});
|
||||||
|
it("Decoder throws on empty string content topic", () => {
|
||||||
|
const wrapper = function (): void {
|
||||||
|
createDecoder("");
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(wrapper).to.throw("Content topic must be specified");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -71,7 +71,11 @@ export class Encoder implements IEncoder {
|
||||||
public contentTopic: string,
|
public contentTopic: string,
|
||||||
public ephemeral: boolean = false,
|
public ephemeral: boolean = false,
|
||||||
public metaSetter?: IMetaSetter
|
public metaSetter?: IMetaSetter
|
||||||
) {}
|
) {
|
||||||
|
if (!contentTopic || contentTopic === "") {
|
||||||
|
throw new Error("Content topic must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array> {
|
async toWire(message: IMessage): Promise<Uint8Array> {
|
||||||
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
||||||
|
@ -117,7 +121,11 @@ export function createEncoder({
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Decoder implements IDecoder<DecodedMessage> {
|
export class Decoder implements IDecoder<DecodedMessage> {
|
||||||
constructor(public contentTopic: string) {}
|
constructor(public contentTopic: string) {
|
||||||
|
if (!contentTopic || contentTopic === "") {
|
||||||
|
throw new Error("Content topic must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
|
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
|
||||||
const protoMessage = proto.WakuMessage.decode(bytes);
|
const protoMessage = proto.WakuMessage.decode(bytes);
|
||||||
|
|
|
@ -9,8 +9,8 @@ describe("Ecies Encryption", function () {
|
||||||
it("Round trip binary encryption [ecies, no signature]", async function () {
|
it("Round trip binary encryption [ecies, no signature]", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ 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, privateKey) => {
|
async (pubSubTopic, contentTopic, payload, privateKey) => {
|
||||||
|
@ -44,8 +44,8 @@ describe("Ecies Encryption", function () {
|
||||||
|
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ minLength: 1 }),
|
fc.uint8Array({ minLength: 1 }),
|
||||||
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
||||||
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
||||||
|
@ -86,8 +86,8 @@ describe("Ecies Encryption", function () {
|
||||||
it("Check meta is set [ecies]", async function () {
|
it("Check meta is set [ecies]", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ 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, privateKey) => {
|
async (pubSubTopic, contentTopic, payload, privateKey) => {
|
||||||
|
@ -130,3 +130,37 @@ describe("Ecies Encryption", function () {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -37,7 +37,11 @@ class Encoder implements IEncoder {
|
||||||
private sigPrivKey?: Uint8Array,
|
private sigPrivKey?: Uint8Array,
|
||||||
public ephemeral: boolean = false,
|
public ephemeral: boolean = false,
|
||||||
public metaSetter?: IMetaSetter
|
public metaSetter?: IMetaSetter
|
||||||
) {}
|
) {
|
||||||
|
if (!contentTopic || contentTopic === "") {
|
||||||
|
throw new Error("Content topic must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
||||||
const protoMessage = await this.toProtoObj(message);
|
const protoMessage = await this.toProtoObj(message);
|
||||||
|
|
|
@ -9,8 +9,8 @@ describe("Symmetric Encryption", function () {
|
||||||
it("Round trip binary encryption [symmetric, no signature]", async function () {
|
it("Round trip binary encryption [symmetric, no signature]", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ 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, symKey) => {
|
async (pubSubTopic, contentTopic, payload, symKey) => {
|
||||||
|
@ -40,8 +40,8 @@ describe("Symmetric Encryption", function () {
|
||||||
it("Round trip binary encryption [symmetric, signature]", async function () {
|
it("Round trip binary encryption [symmetric, signature]", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ minLength: 1 }),
|
fc.uint8Array({ minLength: 1 }),
|
||||||
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
||||||
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
|
||||||
|
@ -75,8 +75,8 @@ describe("Symmetric Encryption", function () {
|
||||||
it("Check meta is set [symmetric]", async function () {
|
it("Check meta is set [symmetric]", async function () {
|
||||||
await fc.assert(
|
await fc.assert(
|
||||||
fc.asyncProperty(
|
fc.asyncProperty(
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.string(),
|
fc.string({ minLength: 1 }),
|
||||||
fc.uint8Array({ 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, symKey) => {
|
async (pubSubTopic, contentTopic, payload, symKey) => {
|
||||||
|
@ -118,3 +118,37 @@ describe("Symmetric Encryption", function () {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Ensures content topic is defined", () => {
|
||||||
|
it("Encoder throws on undefined content topic", () => {
|
||||||
|
const wrapper = function (): void {
|
||||||
|
createEncoder({
|
||||||
|
contentTopic: undefined as unknown as string,
|
||||||
|
symKey: 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: "", symKey: 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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -32,7 +32,11 @@ class Encoder implements IEncoder {
|
||||||
private sigPrivKey?: Uint8Array,
|
private sigPrivKey?: Uint8Array,
|
||||||
public ephemeral: boolean = false,
|
public ephemeral: boolean = false,
|
||||||
public metaSetter?: IMetaSetter
|
public metaSetter?: IMetaSetter
|
||||||
) {}
|
) {
|
||||||
|
if (!contentTopic || contentTopic === "") {
|
||||||
|
throw new Error("Content topic must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
||||||
const protoMessage = await this.toProtoObj(message);
|
const protoMessage = await this.toProtoObj(message);
|
||||||
|
|
Loading…
Reference in New Issue