From aba7b1ec1c9b5122609dea916c7b114e9a3ba66f Mon Sep 17 00:00:00 2001 From: zomars Date: Thu, 21 Jul 2022 22:21:24 -0600 Subject: [PATCH 01/16] Linting --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c806ecc3e4..63abc73795 100644 --- a/README.md +++ b/README.md @@ -186,18 +186,21 @@ Add a deployment or go to an existing one. Activate API or Admin addon Provide your `DATABASE_URL` Now you can call api.cal.com?key=CALCOM_LICENSE_KEY, which will connect to your own databaseUrl. + ## How to deploy We recommend deploying API in vercel. There's some settings that you'll need to setup. -Under Vercel > Your API Deployment > Settings +Under Vercel > Your API Deployment > Settings In General > Build & Development Settings BUILD COMMAND: `yarn turbo run build --scope=@calcom/api --include-dependencies --no-deps` OUTPUT DIRECTORY: `apps/api/.next` See `scripts/vercel-deploy.sh` for more info on how the deployment is done. + ## Environment variables + Lastly API requires an env var for `DATABASE_URL` From 159792831a56fd30b1120b031a7403317c617618 Mon Sep 17 00:00:00 2001 From: zomars Date: Fri, 22 Jul 2022 20:32:10 -0600 Subject: [PATCH 02/16] New import --- lib/helpers/verifyApiKey.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index e5cf0332a3..94945c497c 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,6 +1,6 @@ import { NextMiddleware } from "next-api-middleware"; -import { hashAPIKey } from "@calcom/ee/lib/api/apiKeys"; +import { hashAPIKey } from "@calcom/ee/api-keys/lib/apiKeys"; import { isAdminGuard } from "@lib/utils/isAdmin"; From 60c2f736075122ec3b91a24ef612ad004d257cdb Mon Sep 17 00:00:00 2001 From: zomars Date: Thu, 28 Jul 2022 13:51:20 -0600 Subject: [PATCH 03/16] Migrates EE code --- README.md | 2 +- lib/helpers/verifyApiKey.ts | 2 +- next.config.js | 11 ++++------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 63abc73795..7c2ce6e9ad 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ We're calling several packages from monorepo, this need to be transpiled before "@calcom/app-store", "@calcom/prisma", "@calcom/lib", - "@calcom/ee", + "@calcom/features", ``` ## API Endpoint Validation diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index 94945c497c..b915df6626 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,6 +1,6 @@ import { NextMiddleware } from "next-api-middleware"; -import { hashAPIKey } from "@calcom/ee/api-keys/lib/apiKeys"; +import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys"; import { isAdminGuard } from "@lib/utils/isAdmin"; diff --git a/next.config.js b/next.config.js index 683d8c516b..817b179043 100644 --- a/next.config.js +++ b/next.config.js @@ -3,17 +3,14 @@ const withTM = require("next-transpile-modules")([ "@calcom/app-store", "@calcom/core", - "@calcom/ee", - "@calcom/lib", - "@calcom/prisma", - "@calcom/stripe", - "@calcom/ui", "@calcom/dayjs", "@calcom/emails", - "@calcom/dayjs", "@calcom/embed-core", - "@calcom/dayjs", "@calcom/embed-snippet", + "@calcom/features", + "@calcom/lib", + "@calcom/prisma", + "@calcom/ui", ]); const { withAxiom } = require("next-axiom"); From 915610763e87e310893f75c70729ec655a3df5e1 Mon Sep 17 00:00:00 2001 From: zomars Date: Wed, 3 Aug 2022 11:49:45 -0600 Subject: [PATCH 04/16] Build fixes --- next.config.js | 1 + package.json | 1 + tsconfig.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/next.config.js b/next.config.js index 817b179043..1031c0a949 100644 --- a/next.config.js +++ b/next.config.js @@ -10,6 +10,7 @@ const withTM = require("next-transpile-modules")([ "@calcom/features", "@calcom/lib", "@calcom/prisma", + "@calcom/trpc", "@calcom/ui", ]); const { withAxiom } = require("next-axiom"); diff --git a/package.json b/package.json index 0b4f085b37..3e7c495143 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "dependencies": { "@calcom/app-store-cli": "*", "@calcom/prisma": "*", + "@calcom/trpc": "*", "@sentry/nextjs": "^6.19.7", "bcryptjs": "^2.4.3", "memory-cache": "^0.2.0", diff --git a/tsconfig.json b/tsconfig.json index 2714b86c1c..c230406ae4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,6 @@ "@/*": ["*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "../../packages/types/next-auth.d.ts"], "exclude": ["node_modules", "templates", "auth"] } From 12fe6af995a6dfdf3d550a495560a6965c9e4b41 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Thu, 4 Aug 2022 19:54:25 +0200 Subject: [PATCH 05/16] feat: adds license check --- .env.example | 5 ++++- lib/helpers/verifyApiKey.ts | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index eec3f283f7..c5354bfd7d 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,6 @@ API_KEY_PREFIX=cal_ DATABASE_URL="postgresql://postgres:@localhost:5450/calendso" -NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000 \ No newline at end of file +NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000 + +# Get it in console.cal.com +CALCOM_LICENSE_KEY="" diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index b915df6626..408cc55356 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,6 +1,7 @@ import { NextMiddleware } from "next-api-middleware"; import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys"; +import checkLicense from "@calcom/features/ee/common/server/checkLicense"; import { isAdminGuard } from "@lib/utils/isAdmin"; @@ -14,6 +15,9 @@ export const dateNotInPast = function (date: Date) { // This verifies the apiKey and sets the user if it is valid. export const verifyApiKey: NextMiddleware = async (req, res, next) => { + const hasValidLicense = await checkLicense(process.env.CALCOM_LICENSE_KEY || ""); + if (!hasValidLicense) + return res.status(401).json({ error: "Invalid or missing CALCOM_LICENSE_KEY environment variable" }); const { prisma, userId, isAdmin } = req; // If the user is an admin and using a license key (from customPrisma), skip the apiKey check. if (userId === 0 && isAdmin) { From 244f64d8e7db026f613e7fd84fd2b90c258efb6d Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Thu, 4 Aug 2022 19:57:20 +0200 Subject: [PATCH 06/16] fix: remove unneeded dep from api package.json app-store-cli --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 3e7c495143..17f1cc6fba 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "node-mocks-http": "^1.11.0" }, "dependencies": { - "@calcom/app-store-cli": "*", "@calcom/prisma": "*", "@calcom/trpc": "*", "@sentry/nextjs": "^6.19.7", From 87d8417dd9d84d98e4d8bbf72657a2c70073d84e Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Tue, 9 Aug 2022 19:17:42 +0200 Subject: [PATCH 07/16] feat: add license and readme about copyright --- LICENSE | 42 ++++++++++++++++++++++++++++++++++++++++++ README.md | 17 ++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..fa89efec90 --- /dev/null +++ b/LICENSE @@ -0,0 +1,42 @@ +The Cal.com Enterprise Edition (EE) license (the “EE License”) +Copyright (c) 2020-present Cal.com, Inc + +With regard to the Cal.com Software: + +This software and associated documentation files (the "Software") may only be +used in production, if you (and any entity that you represent) have agreed to, +and are in compliance with, the Cal.com Subscription Terms available +at https://cal.com/terms (the “EE Terms”), or other agreements governing +the use of the Software, as mutually agreed by you and Cal.com, Inc ("Cal.com"), +and otherwise have a valid Cal.com Enterprise Edition subscription ("EE Subscription") +for the correct number of hosts as defined in the EE Terms ("Hosts"). Subject to the foregoing sentence, +you are free to modify this Software and publish patches to the Software. You agree +that Cal.com and/or its licensors (as applicable) retain all right, title and interest in +and to all such modifications and/or patches, and all such modifications and/or +patches may only be used, copied, modified, displayed, distributed, or otherwise +exploited with a valid EE Subscription for the correct number of hosts. +Notwithstanding the foregoing, you may copy and modify the Software for development +and testing purposes, without requiring a subscription. You agree that Cal.com and/or +its licensors (as applicable) retain all right, title and interest in and to all such +modifications. You are not granted any other rights beyond what is expressly stated herein. +Subject to the foregoing, it is forbidden to copy, merge, publish, distribute, sublicense, +and/or sell the Software. + +This EE License applies only to the part of this Software that is not distributed under +the AGPLv3 license. Any part of this Software distributed under the MIT license or which +is served client-side as an image, font, cascading stylesheet (CSS), file which produces +or is compiled, arranged, augmented, or combined into client-side JavaScript, in whole or +in part, is copyrighted under the AGPLv3 license. The full text of this EE License shall +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +For all third party components incorporated into the Cal.com Software, those +components are licensed under the original license provided by the owner of the +applicable component. \ No newline at end of file diff --git a/README.md b/README.md index 7c2ce6e9ad..2e9d04291c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,19 @@ -# Cal.com Public API (Enterprise Only) + + + +# Cal.com Public API - Enterprise Edition + +Welcome to the Public API Enterprise Edition ("/apps/api") of the Cal.com Public API. + +The [/apps/api](https://github.com/calcom/cal.com/tree/main/apps/api) subfolder is the place for our Public API, which we serve at api.cal.com, and enterprise customers can also run [enterprise-grade](https://cal.com/enterprise) + +> _❗ WARNING: This repository is copyrighted (unlike our [main repo](https://github.com/calcom/cal.com)). You are not allowed to use this code to host your own version of app.cal.com without obtaining a proper [license](https://cal.com/pricing?infra) first❗_ This is the public REST api for cal.com. It exposes CRUD Endpoints of all our most important resources. From 8dfc62386dd65c6d0592f99dbb06aeb4591a0bd1 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Tue, 9 Aug 2022 19:39:43 +0200 Subject: [PATCH 08/16] fix: add CALCOM_LICENSE_KEY in env vars section in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e9d04291c..262feb851d 100644 --- a/README.md +++ b/README.md @@ -218,4 +218,4 @@ See `scripts/vercel-deploy.sh` for more info on how the deployment is done. ## Environment variables -Lastly API requires an env var for `DATABASE_URL` +Lastly API requires an env var for `DATABASE_URL` and `CALCOM_LICENSE_KEY` From 7560fdbfc576f7a72ac840f9bef2b9fb92cbe3a3 Mon Sep 17 00:00:00 2001 From: zomars Date: Tue, 9 Aug 2022 17:36:18 -0600 Subject: [PATCH 09/16] Squashed commit of the following: commit fc87557902a85bb7b0ec6f15efa19af12685ff0c Author: zomars Date: Fri Aug 5 15:08:36 2022 -0600 Fixes callbackUrl --- auth/signup.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auth/signup.tsx b/auth/signup.tsx index 8dc735ddab..6a04c71ecc 100644 --- a/auth/signup.tsx +++ b/auth/signup.tsx @@ -9,7 +9,7 @@ import Button from "@calcom/ui/Button"; import { EmailField, PasswordField, TextField } from "@calcom/ui/form/fields"; import { HeadSeo } from "@calcom/web/components/seo/head-seo"; import { asStringOrNull } from "@calcom/web/lib/asStringOrNull"; -import { WEBSITE_URL, WEBAPP_URL } from "@calcom/web/lib/config/constants"; +import { WEBAPP_URL } from "@calcom/web/lib/config/constants"; import prisma from "@calcom/web/lib/prisma"; import { isSAMLLoginEnabled } from "@calcom/web/lib/saml"; import { IS_GOOGLE_LOGIN_ENABLED } from "@calcom/web/server/lib/constants"; @@ -53,7 +53,7 @@ export default function Signup() { .then( async () => await signIn("Cal.com", { - callbackUrl: (`${WEBSITE_URL}/${router.query.callbackUrl}` || "") as string, + callbackUrl: (`${WEBAPP_URL}/${router.query.callbackUrl}` || "") as string, }) ) .catch((err) => { From db937ce00a621e92b066a111ef9f672d638cacb4 Mon Sep 17 00:00:00 2001 From: zomars Date: Thu, 11 Aug 2022 12:47:36 -0600 Subject: [PATCH 10/16] Matches local lint with CI lint --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3e7c495143..e3a07595bb 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "build": "next build", "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next", "dev": "PORT=3002 next dev", - "lint": "next lint", + "lint": "eslint . --ignore-path .gitignore", "lint:report": "eslint . --format json --output-file ../../lint-results/api.json", "lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix", "start": "PORT=3002 next start", From 188ad55686014c13e7b2780b0f3131918369f15c Mon Sep 17 00:00:00 2001 From: zomars Date: Fri, 12 Aug 2022 12:58:32 -0600 Subject: [PATCH 11/16] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 262feb851d..dd278617f0 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ And it makes it easy for anyone to integrate with Cal.com at the application pro ```sh cp apps/api/.env.example apps/api/.env - cp packages/prisma/.env.example packages/prisma/.env + cp .env.example .env ``` 1. Install packages with yarn From 1de91a5124012d62d23eaf30d95c801ee6d7117d Mon Sep 17 00:00:00 2001 From: zomars Date: Fri, 12 Aug 2022 16:37:47 -0600 Subject: [PATCH 12/16] Fixes mismatches --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ac5d07df25..0d6430d98c 100644 --- a/package.json +++ b/package.json @@ -31,15 +31,15 @@ "bcryptjs": "^2.4.3", "memory-cache": "^0.2.0", "modify-response-middleware": "^1.1.0", - "next": "^12.2.0", + "next": "^12.2.5", "next-api-middleware": "^1.0.1", "next-axiom": "^0.10.0", "next-swagger-doc": "^0.3.4", "next-transpile-modules": "^9.0.0", "next-validations": "^0.2.0", - "typescript": "^4.6.4", + "typescript": "^4.7.4", "tzdata": "^1.0.30", "uuid": "^8.3.2", - "zod": "^3.16.0" + "zod": "^3.18.0" } } From bc8623edb8e5633e13cdb457b04f794947afac80 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Mon, 5 Sep 2022 21:01:55 +0200 Subject: [PATCH 14/16] feat: adds me endpoint that returns session info --- pages/api/me.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 pages/api/me.ts diff --git a/pages/api/me.ts b/pages/api/me.ts new file mode 100644 index 0000000000..c66f6919ec --- /dev/null +++ b/pages/api/me.ts @@ -0,0 +1,21 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import { ensureSession } from "@calcom/lib/auth"; +import { defaultHandler, defaultResponder } from "@calcom/lib/server"; + +import { User } from ".prisma/client"; + +async function handler( + req: NextApiRequest, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _res: NextApiResponse +): Promise<{ error?: string; user?: Partial }> { + const session = await ensureSession({ req }); + /* Only admins can opt-in to V2 for now */ + if (!session) return { error: "You need to be logged in" }; + return { user: { ...session.user, email: session.user.email || "" } }; +} + +export default defaultHandler({ + GET: Promise.resolve({ default: defaultResponder(handler) }), +}); From 4d74a6c896bde9ba226b4be6849c8902c230c148 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Mon, 5 Sep 2022 21:16:45 +0200 Subject: [PATCH 15/16] feat: dont use ensureSession, but userId from req --- pages/api/me.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pages/api/me.ts b/pages/api/me.ts index c66f6919ec..e6b1130b63 100644 --- a/pages/api/me.ts +++ b/pages/api/me.ts @@ -1,6 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { ensureSession } from "@calcom/lib/auth"; import { defaultHandler, defaultResponder } from "@calcom/lib/server"; import { User } from ".prisma/client"; @@ -10,10 +9,10 @@ async function handler( // eslint-disable-next-line @typescript-eslint/no-unused-vars _res: NextApiResponse ): Promise<{ error?: string; user?: Partial }> { - const session = await ensureSession({ req }); - /* Only admins can opt-in to V2 for now */ - if (!session) return { error: "You need to be logged in" }; - return { user: { ...session.user, email: session.user.email || "" } }; + if (!prisma) return { error: "Cant connect to database" }; + const user = await prisma.user.findUniqueOrThrow({ where: { id: req.userId } }); + if (!user) return { error: "You need to pass apiKey" }; + return { user }; } export default defaultHandler({ From 731288bcb6d298f7638be46b1a8be967206e55ba Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Mon, 5 Sep 2022 21:31:12 +0200 Subject: [PATCH 16/16] fix: use middleware, refactor into _get --- pages/api/me.ts | 20 -------------------- pages/api/me/_get.ts | 21 +++++++++++++++++++++ pages/api/me/index.ts | 9 +++++++++ 3 files changed, 30 insertions(+), 20 deletions(-) delete mode 100644 pages/api/me.ts create mode 100644 pages/api/me/_get.ts create mode 100644 pages/api/me/index.ts diff --git a/pages/api/me.ts b/pages/api/me.ts deleted file mode 100644 index e6b1130b63..0000000000 --- a/pages/api/me.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from "next"; - -import { defaultHandler, defaultResponder } from "@calcom/lib/server"; - -import { User } from ".prisma/client"; - -async function handler( - req: NextApiRequest, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _res: NextApiResponse -): Promise<{ error?: string; user?: Partial }> { - if (!prisma) return { error: "Cant connect to database" }; - const user = await prisma.user.findUniqueOrThrow({ where: { id: req.userId } }); - if (!user) return { error: "You need to pass apiKey" }; - return { user }; -} - -export default defaultHandler({ - GET: Promise.resolve({ default: defaultResponder(handler) }), -}); diff --git a/pages/api/me/_get.ts b/pages/api/me/_get.ts new file mode 100644 index 0000000000..7fe25139a8 --- /dev/null +++ b/pages/api/me/_get.ts @@ -0,0 +1,21 @@ +import type { NextApiRequest } from "next"; + +import { defaultHandler, defaultResponder } from "@calcom/lib/server"; + +import { schemaUserReadPublic } from "@lib/validations/user"; + +import { User } from ".prisma/client"; + +async function handler(req: NextApiRequest): Promise<{ error?: string; user?: Partial }> { + if (!prisma) return { error: "Cant connect to database" }; + console.log(req); + if (!req.userId) return { error: "No user id found" }; + const data = await prisma.user.findUniqueOrThrow({ where: { id: req.userId } }); + if (!data) return { error: "You need to pass apiKey" }; + const user = schemaUserReadPublic.parse(data); + return { user }; +} + +export default defaultHandler({ + GET: Promise.resolve({ default: defaultResponder(handler) }), +}); diff --git a/pages/api/me/index.ts b/pages/api/me/index.ts new file mode 100644 index 0000000000..fe6357f6bc --- /dev/null +++ b/pages/api/me/index.ts @@ -0,0 +1,9 @@ +import { defaultHandler } from "@calcom/lib/server"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; + +export default withMiddleware("HTTP_GET")( + defaultHandler({ + GET: import("./_get"), + }) +);