Adding new middleware and using it for test action workflow (#6017)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
co-authored by
Peer Richelsen
parent
9eb52bbfb2
commit
1f4e7ca695
@@ -12,7 +12,7 @@ import "react-phone-number-input/style.css";
|
||||
import { SENDER_ID } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { trpc, TRPCClientError } from "@calcom/trpc/react";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
@@ -134,10 +134,16 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||
showToast(t("notification_sent"), "success");
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof HttpError) {
|
||||
const message = `${err.statusCode}: ${err.message}`;
|
||||
showToast(message, "error");
|
||||
let message = t("unexpected_error_try_again");
|
||||
if (err instanceof TRPCClientError) {
|
||||
if (err.message === "rate-limit-exceeded") {
|
||||
message = t("rate_limit_exceeded");
|
||||
}
|
||||
}
|
||||
if (err instanceof HttpError) {
|
||||
message = `${err.statusCode}: ${err.message}`;
|
||||
}
|
||||
showToast(message, "error");
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
import { router, authedProcedure } from "../../trpc";
|
||||
import { router, authedProcedure, authedRateLimitedProcedure } from "../../trpc";
|
||||
|
||||
export const workflowsRouter = router({
|
||||
list: authedProcedure.query(async ({ ctx }) => {
|
||||
@@ -801,7 +801,7 @@ export const workflowsRouter = router({
|
||||
workflow,
|
||||
};
|
||||
}),
|
||||
testAction: authedProcedure
|
||||
testAction: authedRateLimitedProcedure({ intervalInMs: 10000, limit: 3 })
|
||||
.input(
|
||||
z.object({
|
||||
action: z.enum(WORKFLOW_ACTIONS),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import superjson from "superjson";
|
||||
|
||||
import rateLimit from "@calcom/lib/rateLimit";
|
||||
|
||||
import { initTRPC, TRPCError } from "@trpc/server";
|
||||
|
||||
import { Context } from "./createContext";
|
||||
@@ -41,10 +43,41 @@ const isAdminMiddleware = t.middleware(({ ctx, next }) => {
|
||||
},
|
||||
});
|
||||
});
|
||||
interface IRateLimitOptions {
|
||||
intervalInMs: number;
|
||||
limit: number;
|
||||
}
|
||||
const isRateLimitedByUserIdMiddleware = ({ intervalInMs, limit }: IRateLimitOptions) =>
|
||||
t.middleware(({ ctx, next }) => {
|
||||
// validate user exists
|
||||
if (!ctx.user) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
|
||||
const { isRateLimited } = rateLimit({ intervalInMs }).check(limit, ctx.user.id.toString());
|
||||
|
||||
if (isRateLimited) {
|
||||
throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
|
||||
}
|
||||
|
||||
return next({
|
||||
ctx: {
|
||||
// infers that `user` and `session` are non-nullable to downstream procedures
|
||||
session: ctx.session,
|
||||
user: ctx.user,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export const router = t.router;
|
||||
export const mergeRouters = t.mergeRouters;
|
||||
export const middleware = t.middleware;
|
||||
export const publicProcedure = t.procedure.use(perfMiddleware);
|
||||
export const authedProcedure = t.procedure.use(perfMiddleware).use(isAuthedMiddleware);
|
||||
export const authedRateLimitedProcedure = ({ intervalInMs, limit }: IRateLimitOptions) =>
|
||||
t.procedure
|
||||
.use(perfMiddleware)
|
||||
.use(isAuthedMiddleware)
|
||||
.use(isRateLimitedByUserIdMiddleware({ intervalInMs, limit }));
|
||||
|
||||
export const authedAdminProcedure = t.procedure.use(perfMiddleware).use(isAdminMiddleware);
|
||||
|
||||
Reference in New Issue
Block a user