2022-03-29 00:25:24 +00:00
|
|
|
import { NextMiddleware } from "next-api-middleware";
|
2022-03-30 12:17:55 +00:00
|
|
|
|
2022-04-07 23:59:04 +00:00
|
|
|
import { hashAPIKey } from "@calcom/ee/lib/api/apiKeys";
|
2022-03-28 22:27:14 +00:00
|
|
|
|
2022-06-15 18:43:35 +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.
|
2022-04-23 00:05:56 +00:00
|
|
|
export const dateNotInPast = function (date: Date) {
|
2022-04-18 21:24:57 +00:00
|
|
|
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-03-28 22:27:14 +00:00
|
|
|
|
2022-04-23 00:26:35 +00:00
|
|
|
// This verifies the apiKey and sets the user if it is valid.
|
2022-04-30 21:07:21 +00:00
|
|
|
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
|
2022-06-23 17:16:12 +00:00
|
|
|
const { prisma, userId, isAdmin } = req;
|
|
|
|
// If the user is an admin and using a license key (from customPrisma), skip the apiKey check.
|
2022-06-23 21:20:07 +00:00
|
|
|
if (userId === 0 && isAdmin) {
|
|
|
|
await next();
|
|
|
|
return;
|
|
|
|
}
|
2022-06-23 17:16:12 +00:00
|
|
|
// Check if the apiKey query param is provided.
|
2022-04-30 21:07:21 +00:00
|
|
|
if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey provided" });
|
2022-06-23 17:16:12 +00:00
|
|
|
// 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_", "");
|
2022-04-18 21:24:57 +00:00
|
|
|
// Hash the key again before matching against the database records.
|
2022-04-07 23:59:04 +00:00
|
|
|
const hashedKey = hashAPIKey(strippedApiKey);
|
2022-04-18 21:24:57 +00:00
|
|
|
// Check if the hashed api key exists in database.
|
2022-04-30 21:07:21 +00:00
|
|
|
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
2022-06-23 17:16:12 +00:00
|
|
|
// If cannot find any api key. Throw a 401 Unauthorized.
|
2022-04-30 21:07:21 +00:00
|
|
|
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
|
|
|
}
|
2022-04-30 21:07:21 +00:00
|
|
|
if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
|
2022-06-23 17:16:12 +00:00
|
|
|
// save the user id in the request for later use
|
2022-04-30 21:07:21 +00:00
|
|
|
req.userId = apiKey.userId;
|
2022-06-23 17:16:12 +00:00
|
|
|
// save the isAdmin boolean here for later use
|
2022-06-23 22:26:40 +00:00
|
|
|
req.isAdmin = await isAdminGuard(req);
|
2022-06-15 18:43:35 +00:00
|
|
|
|
2022-04-22 01:36:33 +00:00
|
|
|
await next();
|
2022-03-29 00:25:24 +00:00
|
|
|
};
|