chore: Rate limit top level of public booking pages (#25056)
* chore: Rate limit top level of public booking pages * Prefix rateLimit keys * Adding more rate limits --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com>
This commit is contained in:
1 parent
fd390f9d43
commit
e239b67171
4 files changed
+37
-2
No files matched your search
@@ -2,6 +2,9 @@ import type { GetServerSidePropsContext } from "next";
|
||||
import z from "zod";
|
||||
|
||||
import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||
import getIP from "@calcom/lib/getIP";
|
||||
import { piiHasher } from "@calcom/lib/server/PiiHasher";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
@@ -16,6 +19,12 @@ const paramsSchema = z.object({
|
||||
});
|
||||
|
||||
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
const requestorIp = getIP(ctx.req as unknown as Request);
|
||||
await checkRateLimitAndThrowError({
|
||||
rateLimitingType: "core",
|
||||
identifier: `[orgSlug]/[user]/[type]-${piiHasher.hash(requestorIp)}`,
|
||||
});
|
||||
|
||||
const { user: teamOrUserSlugOrDynamicGroup, orgSlug, type } = paramsSchema.parse(ctx.params);
|
||||
const team = await prisma.team.findFirst({
|
||||
where: {
|
||||
|
||||
@@ -9,7 +9,10 @@ import { getOrganizationSEOSettings } from "@calcom/features/ee/organizations/li
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { getBrandingForEventType } from "@calcom/features/profile/lib/getBranding";
|
||||
import { shouldHideBrandingForTeamEvent } from "@calcom/features/profile/lib/hideBranding";
|
||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
|
||||
import getIP from "@calcom/lib/getIP";
|
||||
import { piiHasher } from "@calcom/lib/server/PiiHasher";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { User } from "@calcom/prisma/client";
|
||||
@@ -28,6 +31,11 @@ function hasApiV2RouteInEnv() {
|
||||
}
|
||||
|
||||
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
|
||||
const requestorIp = getIP(context.req as unknown as Request);
|
||||
await checkRateLimitAndThrowError({
|
||||
rateLimitingType: "core",
|
||||
identifier: `team/[slug]/[type]-${piiHasher.hash(requestorIp)}`,
|
||||
});
|
||||
const { req, params, query } = context;
|
||||
const session = await getServerSession({ req });
|
||||
const { slug: teamSlug, type: meetingSlug } = paramsSchema.parse(params);
|
||||
|
||||
@@ -11,6 +11,9 @@ import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEv
|
||||
import { EventRepository } from "@calcom/features/eventtypes/repositories/EventRepository";
|
||||
import { shouldHideBrandingForUserEvent } from "@calcom/features/profile/lib/hideBranding";
|
||||
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
|
||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||
import getIP from "@calcom/lib/getIP";
|
||||
import { piiHasher } from "@calcom/lib/server/PiiHasher";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { BookingStatus, RedirectType } from "@calcom/prisma/enums";
|
||||
@@ -63,6 +66,7 @@ async function processReschedule({
|
||||
(booking?.eventTypeId === props.eventData?.id &&
|
||||
(booking.status !== BookingStatus.CANCELLED ||
|
||||
allowRescheduleForCancelledBooking ||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
!!(props.eventData as any)?.allowReschedulingCancelledBookings))
|
||||
) {
|
||||
props.booking = booking;
|
||||
@@ -314,6 +318,12 @@ const paramsSchema = z.object({
|
||||
// Booker page fetches a tiny bit of data server side, to determine early
|
||||
// whether the page should show an away state or dynamic booking not allowed.
|
||||
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
|
||||
const requestorIp = getIP(context.req as unknown as Request);
|
||||
await checkRateLimitAndThrowError({
|
||||
rateLimitingType: "core",
|
||||
identifier: `[user]/[type]-${piiHasher.hash(requestorIp)}`,
|
||||
});
|
||||
|
||||
const { user } = paramsSchema.parse(context.params);
|
||||
const isDynamicGroup = user.length > 1;
|
||||
|
||||
|
||||
@@ -8,11 +8,14 @@ import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents";
|
||||
import { getEventTypesPublic } from "@calcom/features/eventtypes/lib/getEventTypesPublic";
|
||||
import { getBrandingForUser } from "@calcom/features/profile/lib/getBranding";
|
||||
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
|
||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||
import { DEFAULT_DARK_BRAND_COLOR, DEFAULT_LIGHT_BRAND_COLOR } from "@calcom/lib/constants";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import getIP from "@calcom/lib/getIP";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { piiHasher } from "@calcom/lib/server/PiiHasher";
|
||||
import { stripMarkdown } from "@calcom/lib/stripMarkdown";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { EventType, User } from "@calcom/prisma/client";
|
||||
@@ -79,6 +82,12 @@ type UserPageProps = {
|
||||
} & EmbedProps;
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<UserPageProps> = async (context) => {
|
||||
// handle IP based rate limiting
|
||||
const requestorIp = getIP(context.req as unknown as Request);
|
||||
await checkRateLimitAndThrowError({
|
||||
rateLimitingType: "core",
|
||||
identifier: `[user]-${piiHasher.hash(requestorIp)}`,
|
||||
});
|
||||
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req, context.params?.orgSlug);
|
||||
const usernameList = getUsernameList(context.query.user as string);
|
||||
const isARedirectFromNonOrgLink = context.query.orgRedirection === "true";
|
||||
@@ -144,8 +153,7 @@ export const getServerSideProps: GetServerSideProps<UserPageProps> = async (cont
|
||||
theme: branding.theme,
|
||||
brandColor: branding.brandColor ?? DEFAULT_LIGHT_BRAND_COLOR,
|
||||
avatarUrl: user.avatarUrl,
|
||||
darkBrandColor:
|
||||
branding.darkBrandColor ?? DEFAULT_DARK_BRAND_COLOR,
|
||||
darkBrandColor: branding.darkBrandColor ?? DEFAULT_DARK_BRAND_COLOR,
|
||||
allowSEOIndexing: user.allowSEOIndexing ?? true,
|
||||
username: user.username,
|
||||
organization: user.profile.organization,
|
||||
|
||||
Reference in new issue
Block a user