fix: Allow use of validations middleware in plugins
This commit is contained in:
38
plugins/webhooks/server/api/schema.ts
Normal file
38
plugins/webhooks/server/api/schema.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const WebhookSubscriptionsCreateSchema = z.object({
|
||||||
|
body: z.object({
|
||||||
|
name: z.string(),
|
||||||
|
url: z.string().url(),
|
||||||
|
secret: z.string().optional(),
|
||||||
|
events: z.array(z.string()),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type WebhookSubscriptionsCreateReq = z.infer<
|
||||||
|
typeof WebhookSubscriptionsCreateSchema
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const WebhookSubscriptionsUpdateSchema = z.object({
|
||||||
|
body: z.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
name: z.string(),
|
||||||
|
url: z.string().url(),
|
||||||
|
secret: z.string().optional(),
|
||||||
|
events: z.array(z.string()),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type WebhookSubscriptionsUpdateReq = z.infer<
|
||||||
|
typeof WebhookSubscriptionsUpdateSchema
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const WebhookSubscriptionsDeleteSchema = z.object({
|
||||||
|
body: z.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type WebhookSubscriptionsDeleteReq = z.infer<
|
||||||
|
typeof WebhookSubscriptionsDeleteSchema
|
||||||
|
>;
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import Router from "koa-router";
|
import Router from "koa-router";
|
||||||
import compact from "lodash/compact";
|
import compact from "lodash/compact";
|
||||||
import isEmpty from "lodash/isEmpty";
|
import isEmpty from "lodash/isEmpty";
|
||||||
import { ValidationError } from "@server/errors";
|
|
||||||
import auth from "@server/middlewares/authentication";
|
import auth from "@server/middlewares/authentication";
|
||||||
|
import validate from "@server/middlewares/validate";
|
||||||
import { WebhookSubscription, Event } from "@server/models";
|
import { WebhookSubscription, Event } from "@server/models";
|
||||||
import { authorize } from "@server/policies";
|
import { authorize } from "@server/policies";
|
||||||
import pagination from "@server/routes/api/middlewares/pagination";
|
import pagination from "@server/routes/api/middlewares/pagination";
|
||||||
import { WebhookSubscriptionEvent, APIContext } from "@server/types";
|
import { WebhookSubscriptionEvent, APIContext } from "@server/types";
|
||||||
import { assertArray, assertPresent, assertUuid } from "@server/validation";
|
|
||||||
import presentWebhookSubscription from "../presenters/webhookSubscription";
|
import presentWebhookSubscription from "../presenters/webhookSubscription";
|
||||||
|
import * as T from "./schema";
|
||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
|
|
||||||
@@ -38,18 +38,13 @@ router.post(
|
|||||||
router.post(
|
router.post(
|
||||||
"webhookSubscriptions.create",
|
"webhookSubscriptions.create",
|
||||||
auth({ admin: true }),
|
auth({ admin: true }),
|
||||||
async (ctx: APIContext) => {
|
validate(T.WebhookSubscriptionsCreateSchema),
|
||||||
|
async (ctx: APIContext<T.WebhookSubscriptionsCreateReq>) => {
|
||||||
const { user } = ctx.state.auth;
|
const { user } = ctx.state.auth;
|
||||||
authorize(user, "createWebhookSubscription", user.team);
|
authorize(user, "createWebhookSubscription", user.team);
|
||||||
|
|
||||||
const { name, url, secret } = ctx.request.body;
|
const { name, url, secret } = ctx.input.body;
|
||||||
const events: string[] = compact(ctx.request.body.events);
|
const events: string[] = compact(ctx.input.body.events);
|
||||||
assertPresent(name, "name is required");
|
|
||||||
assertPresent(url, "url is required");
|
|
||||||
assertArray(events, "events is required");
|
|
||||||
if (events.length === 0) {
|
|
||||||
throw ValidationError("events are required");
|
|
||||||
}
|
|
||||||
|
|
||||||
const webhookSubscription = await WebhookSubscription.create({
|
const webhookSubscription = await WebhookSubscription.create({
|
||||||
name,
|
name,
|
||||||
@@ -84,9 +79,9 @@ router.post(
|
|||||||
router.post(
|
router.post(
|
||||||
"webhookSubscriptions.delete",
|
"webhookSubscriptions.delete",
|
||||||
auth({ admin: true }),
|
auth({ admin: true }),
|
||||||
async (ctx: APIContext) => {
|
validate(T.WebhookSubscriptionsDeleteSchema),
|
||||||
const { id } = ctx.request.body;
|
async (ctx: APIContext<T.WebhookSubscriptionsDeleteReq>) => {
|
||||||
assertUuid(id, "id is required");
|
const { id } = ctx.input.body;
|
||||||
const { user } = ctx.state.auth;
|
const { user } = ctx.state.auth;
|
||||||
const webhookSubscription = await WebhookSubscription.findByPk(id);
|
const webhookSubscription = await WebhookSubscription.findByPk(id);
|
||||||
|
|
||||||
@@ -117,21 +112,14 @@ router.post(
|
|||||||
router.post(
|
router.post(
|
||||||
"webhookSubscriptions.update",
|
"webhookSubscriptions.update",
|
||||||
auth({ admin: true }),
|
auth({ admin: true }),
|
||||||
async (ctx: APIContext) => {
|
validate(T.WebhookSubscriptionsUpdateSchema),
|
||||||
const { id } = ctx.request.body;
|
async (ctx: APIContext<T.WebhookSubscriptionsUpdateReq>) => {
|
||||||
assertUuid(id, "id is required");
|
const { id, name, url, secret } = ctx.input.body;
|
||||||
const { user } = ctx.state.auth;
|
const { user } = ctx.state.auth;
|
||||||
|
const events: string[] = compact(ctx.input.body.events);
|
||||||
const { name, url, secret } = ctx.request.body;
|
const webhookSubscription = await WebhookSubscription.findByPk(id, {
|
||||||
const events: string[] = compact(ctx.request.body.events);
|
rejectOnEmpty: true,
|
||||||
assertPresent(name, "name is required");
|
});
|
||||||
assertPresent(url, "url is required");
|
|
||||||
assertArray(events, "events is required");
|
|
||||||
if (events.length === 0) {
|
|
||||||
throw ValidationError("events are required");
|
|
||||||
}
|
|
||||||
|
|
||||||
const webhookSubscription = await WebhookSubscription.findByPk(id);
|
|
||||||
|
|
||||||
authorize(user, "update", webhookSubscription);
|
authorize(user, "update", webhookSubscription);
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,11 @@ glob
|
|||||||
.forEach((filePath: string) => {
|
.forEach((filePath: string) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const pkg: Router = require(path.join(process.cwd(), filePath)).default;
|
const pkg: Router = require(path.join(process.cwd(), filePath)).default;
|
||||||
router.use("/", pkg.routes());
|
|
||||||
Logger.debug("lifecycle", `Registered API routes for ${filePath}`);
|
if (pkg && "routes" in pkg) {
|
||||||
|
router.use("/", pkg.routes());
|
||||||
|
Logger.debug("lifecycle", `Registered API routes for ${filePath}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
|
|||||||
Reference in New Issue
Block a user