fix: don't require apiKey if already using customPrisma with calcom license key
parent
b6729d8b82
commit
c3996221e1
|
@ -4,7 +4,6 @@ import { NextMiddleware } from "next-api-middleware";
|
||||||
|
|
||||||
import { PRISMA_CLIENT_CACHING_TIME } from "@calcom/api/lib/constants";
|
import { PRISMA_CLIENT_CACHING_TIME } from "@calcom/api/lib/constants";
|
||||||
// import prismaAdmin from "@calcom/console/modules/common/utils/prisma";
|
// import prismaAdmin from "@calcom/console/modules/common/utils/prisma";
|
||||||
import { asStringOrUndefined } from "@calcom/lib/asStringOrNull";
|
|
||||||
import { CONSOLE_URL } from "@calcom/lib/constants";
|
import { CONSOLE_URL } from "@calcom/lib/constants";
|
||||||
import { prisma, customPrisma } from "@calcom/prisma";
|
import { prisma, customPrisma } from "@calcom/prisma";
|
||||||
|
|
||||||
|
@ -18,14 +17,9 @@ export const customPrismaClient: NextMiddleware = async (req, res, next) => {
|
||||||
req.prisma = prisma;
|
req.prisma = prisma;
|
||||||
await next();
|
await next();
|
||||||
} else {
|
} else {
|
||||||
const id = asStringOrUndefined(key);
|
// If we have a key, we check if the deployment matching the key, has a databaseUrl value set.
|
||||||
|
|
||||||
// If we have a key, we check if it is valid.
|
|
||||||
// const deployment = await prismaAdmin.deployment.findUnique({
|
|
||||||
// where: { key },
|
|
||||||
// });
|
|
||||||
const databaseUrl = await fetch(
|
const databaseUrl = await fetch(
|
||||||
`${process.env.NEXT_PUBLIC_CONSOLE_URL || CONSOLE_URL}/api/deployments/database?key=${id}`
|
`${process.env.NEXT_PUBLIC_CONSOLE_URL || CONSOLE_URL}/api/deployments/database?key=${key}`
|
||||||
)
|
)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((res) => res.databaseUrl);
|
.then((res) => res.databaseUrl);
|
||||||
|
@ -34,10 +28,11 @@ export const customPrismaClient: NextMiddleware = async (req, res, next) => {
|
||||||
res.status(400).json({ error: "no databaseUrl set up at your instance yet" });
|
res.status(400).json({ error: "no databaseUrl set up at your instance yet" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// FIXME: Add some checks for the databaseUrl to make sure it is valid. (e.g. not a localhost)
|
||||||
const hashedUrl = await hash(databaseUrl, 12);
|
const hashedUrl = await hash(databaseUrl, 12);
|
||||||
|
|
||||||
const cachedPrisma = cache.get(hashedUrl);
|
const cachedPrisma = cache.get(hashedUrl);
|
||||||
|
/* We cache each cusotm prisma client for 24h to avoid too many requests to the database. */
|
||||||
if (!cachedPrisma) {
|
if (!cachedPrisma) {
|
||||||
cache.put(
|
cache.put(
|
||||||
hashedUrl,
|
hashedUrl,
|
||||||
|
@ -46,6 +41,13 @@ export const customPrismaClient: NextMiddleware = async (req, res, next) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
req.prisma = customPrisma({ datasources: { db: { url: databaseUrl } } });
|
req.prisma = customPrisma({ datasources: { db: { url: databaseUrl } } });
|
||||||
|
/* @note:
|
||||||
|
In order to skip verifyApiKey for customPrisma requests,
|
||||||
|
we pass isAdmin true, and userId 0, if we detect them later,
|
||||||
|
we skip verifyApiKey logic and pass onto next middleware instead.
|
||||||
|
*/
|
||||||
|
req.isAdmin = true;
|
||||||
|
req.userId = 0;
|
||||||
}
|
}
|
||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,26 +14,26 @@ export const dateNotInPast = function (date: Date) {
|
||||||
|
|
||||||
// This verifies the apiKey and sets the user if it is valid.
|
// This verifies the apiKey and sets the user if it is valid.
|
||||||
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
|
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
|
||||||
const { prisma } = req;
|
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) await next();
|
||||||
|
// Check if the apiKey query param is provided.
|
||||||
if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey 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_"
|
||||||
// We remove the prefix from the user provided api_key. If no env set default to "cal_"
|
|
||||||
const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", "");
|
const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", "");
|
||||||
|
|
||||||
// Hash the key again before matching against the database records.
|
// Hash the key again before matching against the database records.
|
||||||
const hashedKey = hashAPIKey(strippedApiKey);
|
const hashedKey = hashAPIKey(strippedApiKey);
|
||||||
// Check if the hashed api key exists in database.
|
// Check if the hashed api key exists in database.
|
||||||
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
||||||
// console.log("apiKey", apiKey);
|
// If cannot find any api key. Throw a 401 Unauthorized.
|
||||||
// If we cannot find any api key. Throw a 401 Unauthorized.
|
|
||||||
if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
||||||
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
|
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
|
||||||
return res.status(401).json({ error: "This apiKey is expired" });
|
return res.status(401).json({ error: "This apiKey is expired" });
|
||||||
}
|
}
|
||||||
if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
|
if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
|
||||||
/* We save the user id in the request for later use */
|
// save the user id in the request for later use
|
||||||
req.userId = apiKey.userId;
|
req.userId = apiKey.userId;
|
||||||
/* We save the isAdmin boolean here for later use */
|
// save the isAdmin boolean here for later use
|
||||||
req.isAdmin = await isAdminGuard(req.userId, prisma);
|
req.isAdmin = await isAdminGuard(req.userId, prisma);
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
|
|
Loading…
Reference in New Issue