From 8bb2b1bb766ac9dc7fcfa189d6391be05a714d36 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 4 Aug 2020 11:38:48 +0200 Subject: [PATCH 1/2] Improve docs of isNonNullObject --- packages/utils/src/typechecks.ts | 7 ++++++- packages/utils/types/typechecks.d.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/typechecks.ts b/packages/utils/src/typechecks.ts index 664fcc53..40faa05d 100644 --- a/packages/utils/src/typechecks.ts +++ b/packages/utils/src/typechecks.ts @@ -1,5 +1,10 @@ /** - * Checks if data is a non-null object (i.e. matches the TypeScript object type) + * Checks if data is a non-null object (i.e. matches the TypeScript object type). + * + * Note: this returns true for arrays, which are objects in JavaScript + * even though array and object are different types in JSON. + * + * @see https://www.typescriptlang.org/docs/handbook/basic-types.html#object */ export function isNonNullObject(data: unknown): data is object { return typeof data === "object" && data !== null; diff --git a/packages/utils/types/typechecks.d.ts b/packages/utils/types/typechecks.d.ts index 3e911797..68c29628 100644 --- a/packages/utils/types/typechecks.d.ts +++ b/packages/utils/types/typechecks.d.ts @@ -1,5 +1,10 @@ /** - * Checks if data is a non-null object (i.e. matches the TypeScript object type) + * Checks if data is a non-null object (i.e. matches the TypeScript object type). + * + * Note: this returns true for arrays, which are objects in JavaScript + * even though array and object are different types in JSON. + * + * @see https://www.typescriptlang.org/docs/handbook/basic-types.html#object */ export declare function isNonNullObject(data: unknown): data is object; /** From 7dfdec3da30108894461d1b695b65a8080ccd06f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 4 Aug 2020 11:23:29 +0200 Subject: [PATCH 2/2] Improve type checks of RequestParser.parseCreditBody --- packages/faucet/src/api/requestparser.spec.ts | 12 ++++++++++++ packages/faucet/src/api/requestparser.ts | 10 ++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/faucet/src/api/requestparser.spec.ts b/packages/faucet/src/api/requestparser.spec.ts index 73512029..aeb53e38 100644 --- a/packages/faucet/src/api/requestparser.spec.ts +++ b/packages/faucet/src/api/requestparser.spec.ts @@ -7,6 +7,18 @@ describe("RequestParser", () => { }); it("throws for invalid credit requests", () => { + // body not a dictionary + { + expect(() => RequestParser.parseCreditBody("foo")).toThrowError(/Request body must be a dictionary./i); + expect(() => RequestParser.parseCreditBody(null)).toThrowError(/Request body must be a dictionary./i); + expect(() => RequestParser.parseCreditBody(42)).toThrowError(/Request body must be a dictionary./i); + expect(() => RequestParser.parseCreditBody([])).toThrowError(/Request body must be a dictionary./i); + expect(() => RequestParser.parseCreditBody(true)).toThrowError(/Request body must be a dictionary./i); + expect(() => RequestParser.parseCreditBody(undefined)).toThrowError( + /Request body must be a dictionary./i, + ); + } + // address unset { const body = { ticker: "TKN" }; diff --git a/packages/faucet/src/api/requestparser.ts b/packages/faucet/src/api/requestparser.ts index db938f73..77dda0f7 100644 --- a/packages/faucet/src/api/requestparser.ts +++ b/packages/faucet/src/api/requestparser.ts @@ -1,3 +1,5 @@ +import { isNonNullObject } from "@cosmjs/utils"; + import { HttpError } from "./httperror"; export interface CreditRequestBodyData { @@ -8,8 +10,12 @@ export interface CreditRequestBodyData { } export class RequestParser { - public static parseCreditBody(body: any): CreditRequestBodyData { - const { address, ticker } = body; + public static parseCreditBody(body: unknown): CreditRequestBodyData { + if (!isNonNullObject(body) || Array.isArray(body)) { + throw new HttpError(400, "Request body must be a dictionary."); + } + + const { address, ticker } = body as any; if (typeof address !== "string") { throw new HttpError(400, "Property 'address' must be a string.");