Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,5 @@ DATABASE_CHUNK_SIZE=
# Service Account Encryption Key for encrypting/decrypting service account keys
# You can use: `openssl rand -base64 24` to generate one
CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY=

VERCEL_BOTID_ENABLED=
24 changes: 24 additions & 0 deletions apps/web/instrumentation-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The added config here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs";
import { initBotId } from "botid/client/core";

if (process.env.NODE_ENV === "production") {
Sentry.init({
Expand Down Expand Up @@ -43,6 +44,29 @@ if (process.env.NODE_ENV === "production") {
});
}

if (process.env.NEXT_PUBLIC_VERCEL_BOTID_ENABLED === "true") {
initBotId({
protect: [
{
path: "/router",
method: "GET",
},
{
path: "/router",
method: "POST",
},
Comment on lines +54 to +57
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was getting this message so thought I would just include these in the config

Possible misconfiguration of Vercel BotId. Ensure that the client-side protection is properly configured for 'POST <your protected endpoint>'. Add the following item to your BotId client side protection: { path: '<your protected endpoint>', method: 'POST', }

{
path: "/router/embed",
method: "GET",
},
{
path: "/router/embed",
method: "POST",
},
],
});
}

export function onRouterTransitionStart(url: string, navigationType: "push" | "replace" | "traverse") {
if (process.env.NODE_ENV === "production") {
Sentry.captureRouterTransitionStart(url, navigationType);
Expand Down
1 change: 1 addition & 0 deletions apps/web/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { extendEventData, nextCollectBasicSettings } from "@calcom/lib/telemetry

import { getCspHeader, getCspNonce } from "@lib/csp";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const safeGet = async <T = any>(key: string): Promise<T | undefined> => {
try {
return get<T>(key);
Expand Down
8 changes: 8 additions & 0 deletions apps/web/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const { withBotId } = require("botid/next/config");

require("dotenv").config({ path: "../../.env" });

const englishTranslation = require("./public/static/locales/en/common.json");
const { withAxiom } = require("next-axiom");
const { version } = require("./package.json");
Expand Down Expand Up @@ -107,6 +110,11 @@ const informAboutDuplicateTranslations = () => {

informAboutDuplicateTranslations();
const plugins = [];

if (process.env.NEXT_PUBLIC_VERCEL_BOTID_ENABLED === "true") {
plugins.push(withBotId);
}

if (process.env.ANALYZE === "true") {
// only load dependency if env `ANALYZE` was set
const withBundleAnalyzer = require("@next/bundle-analyzer")({
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"async": "^3.2.4",
"bcp-47-match": "^2.0.3",
"bcryptjs": "^2.4.3",
"botid": "^1.5.4",
"classnames": "^2.3.1",
"dompurify": "^3.1.7",
"dotenv-cli": "^6.0.0",
Expand Down
17 changes: 16 additions & 1 deletion apps/web/server/lib/router/getServerSideProps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { wrapGetServerSidePropsWithSentry } from "@sentry/nextjs";
import { checkBotId } from "botid/server";
import type { GetServerSidePropsContext } from "next";

import { getRoutedUrl, hasEmbedPath } from "@calcom/features/routing-forms/lib/getRoutedUrl";
Expand All @@ -8,12 +9,26 @@ import { TRPCError } from "@trpc/server";
export const getServerSideProps = wrapGetServerSidePropsWithSentry(async function getServerSideProps(
context: GetServerSidePropsContext
) {
const isEmbed = hasEmbedPath(context.req.url || "");

if (!process.env.NEXT_PUBLIC_IS_E2E && process.env.NEXT_PUBLIC_VERCEL_BOTID_ENABLED) {
const verification = await checkBotId();
if (verification.isBot) {
return {
props: {
isEmbed,
message: null,
form: null,
errorMessage: "Access denied",
},
};
}
}
try {
return await getRoutedUrl(context);
} catch (error) {
if (error instanceof TRPCError && error.code === "TOO_MANY_REQUESTS") {
context.res.statusCode = 429;
const isEmbed = hasEmbedPath(context.req.url || "");

return {
props: {
Expand Down
1 change: 1 addition & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
"UNKEY_ROOT_KEY",
"USERNAME_BLACKLIST_URL",
"VERCEL_ENV",
"VERCEL_BOTID_ENABLED",
"VERCEL_URL",
"VITAL_API_KEY",
"VITAL_DEVELOPMENT_MODE",
Expand Down
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4294,6 +4294,7 @@ __metadata:
autoprefixer: ^10.4.12
bcp-47-match: ^2.0.3
bcryptjs: ^2.4.3
botid: ^1.5.4
classnames: ^2.3.1
cron: ^3.1.7
detect-port: ^1.3.0
Expand Down Expand Up @@ -21282,6 +21283,21 @@ __metadata:
languageName: node
linkType: hard

"botid@npm:^1.5.4":
version: 1.5.4
resolution: "botid@npm:1.5.4"
peerDependencies:
next: "*"
react: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
next:
optional: true
react:
optional: true
checksum: e549a27a72369861e02141a4d5f11ab0e561a055344cf2c45869644eddf6fcab4db5d33e8716067cb7c6181e6a6c47a6e98fa3c627c448ce82d2d5df90e81f4e
languageName: node
linkType: hard

"bottleneck@npm:^2.15.3, bottleneck@npm:^2.19.5":
version: 2.19.5
resolution: "bottleneck@npm:2.19.5"
Expand Down
Loading