diff --git a/server/api/users.js b/server/api/users.js index c97d027f..491f8844 100644 --- a/server/api/users.js +++ b/server/api/users.js @@ -258,7 +258,7 @@ router.post("users.activate", auth(), async (ctx) => { router.post("users.invite", auth(), async (ctx) => { const { invites } = ctx.body; - ctx.assertPresent(invites, "invites is required"); + ctx.assertArray(invites, "invites must be an array"); const { user } = ctx.state; const team = await Team.findByPk(user.teamId); diff --git a/server/api/users.test.js b/server/api/users.test.js index 59b80e4b..f1732884 100644 --- a/server/api/users.test.js +++ b/server/api/users.test.js @@ -167,6 +167,17 @@ describe("#users.invite", () => { expect(body.data.sent.length).toEqual(1); }); + it("should require invites to be an array", async () => { + const user = await buildUser(); + const res = await server.post("/api/users.invite", { + body: { + token: user.getJwtToken(), + invites: { email: "test@example.com", name: "Test", guest: false }, + }, + }); + expect(res.status).toEqual(400); + }); + it("should require admin", async () => { const user = await buildUser(); const res = await server.post("/api/users.invite", { diff --git a/server/middlewares/validation.js b/server/middlewares/validation.js index 52bbb301..c31d635b 100644 --- a/server/middlewares/validation.js +++ b/server/middlewares/validation.js @@ -1,5 +1,6 @@ // @flow import { type Context } from "koa"; +import { isArrayLike } from "lodash"; import validator from "validator"; import { validateColorHex } from "../../shared/utils/color"; import { validateIndexCharacters } from "../../shared/utils/indexCharacters"; @@ -13,6 +14,12 @@ export default function validation() { } }; + ctx.assertArray = (value, message) => { + if (!isArrayLike(value)) { + throw new ValidationError(message); + } + }; + ctx.assertIn = (value, options, message) => { if (!options.includes(value)) { throw new ValidationError(message);