cal.pub0.org/apps/api/lib/helpers/verifyApiKey.ts

49 lines
2.2 KiB
TypeScript
Raw Normal View History

2023-02-16 21:01:40 +00:00
import type { NextMiddleware } from "next-api-middleware";
2022-03-30 12:17:55 +00:00
2022-07-28 19:51:20 +00:00
import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys";
2022-08-04 17:54:25 +00:00
import checkLicense from "@calcom/features/ee/common/server/checkLicense";
import { IS_PRODUCTION } from "@calcom/lib/constants";
2022-11-25 13:56:58 +00:00
import { isAdminGuard } from "~/lib/utils/isAdmin";
2022-04-23 00:26:35 +00:00
// Used to check if the apiKey is not expired, could be extracted if reused. but not for now.
export const dateNotInPast = function (date: Date) {
const now = new Date();
2022-04-23 03:37:36 +00:00
if (now.setHours(0, 0, 0, 0) > date.setHours(0, 0, 0, 0)) {
2022-03-30 12:17:55 +00:00
return true;
}
};
2022-04-23 00:26:35 +00:00
// This verifies the apiKey and sets the user if it is valid.
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
2023-02-08 17:55:46 +00:00
const { prisma, isCustomPrisma, isAdmin } = req;
const hasValidLicense = await checkLicense(prisma);
if (!hasValidLicense && IS_PRODUCTION)
2022-08-04 17:54:25 +00:00
return res.status(401).json({ error: "Invalid or missing CALCOM_LICENSE_KEY environment variable" });
// If the user is an admin and using a license key (from customPrisma), skip the apiKey check.
if (isCustomPrisma && isAdmin) {
await next();
return;
}
// Check if the apiKey query param is provided.
if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey provided" });
// remove the prefix from the user provided api_key. If no env set default to "cal_"
2022-05-18 19:48:13 +00:00
const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", "");
// Hash the key again before matching against the database records.
const hashedKey = hashAPIKey(strippedApiKey);
// Check if the hashed api key exists in database.
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
// If cannot find any api key. Throw a 401 Unauthorized.
if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
2022-04-23 00:26:35 +00:00
return res.status(401).json({ error: "This apiKey is expired" });
2022-04-22 01:36:33 +00:00
}
if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
// save the user id in the request for later use
req.userId = apiKey.userId;
// save the isAdmin boolean here for later use
req.isAdmin = await isAdminGuard(req);
req.isCustomPrisma = false;
2022-04-22 01:36:33 +00:00
await next();
};