Fixes: with hariom help for running api in prod for swagger even in dev
parent
167a42156d
commit
a2d16800aa
|
@ -4,6 +4,21 @@ import { NextMiddleware } from "next-api-middleware";
|
|||
export const addRequestId: NextMiddleware = async (_req, res, next) => {
|
||||
// Apply header with unique ID to every request
|
||||
res.setHeader("Calcom-Response-ID", nanoid());
|
||||
// Add all headers here instead of next.config.js as it is throwing error( Cannot set headers after they are sent to the client) for OPTIONS method
|
||||
// It is known to happen only in Dev Mode.
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS, PATCH, DELETE, POST, PUT");
|
||||
res.setHeader(
|
||||
"Access-Control-Allow-Headers",
|
||||
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Content-Type, api_key, Authorization"
|
||||
);
|
||||
|
||||
// Ensure all OPTIONS request are automatically successful. Headers are already set above.
|
||||
if (_req.method === "OPTIONS") {
|
||||
res.status(200).end();
|
||||
return;
|
||||
}
|
||||
// Let remaining middleware and API route execute
|
||||
await next();
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ export const httpMethod = (allowedHttpMethod: "GET" | "POST" | "PATCH" | "DELETE
|
|||
// that checks if it's just a string or an array and apply the correct logic to both cases.
|
||||
export const httpMethods = (allowedHttpMethod: string[]): NextMiddleware => {
|
||||
return async function (req, res, next) {
|
||||
if (allowedHttpMethod.map((method) => method === req.method)) {
|
||||
if (allowedHttpMethod.some((method) => method === req.method || req.method == "OPTIONS")) {
|
||||
await next();
|
||||
} else {
|
||||
res.status(405).json({ message: `Only ${allowedHttpMethod} Method allowed` });
|
||||
|
|
|
@ -8,8 +8,6 @@ import prisma from "@calcom/prisma";
|
|||
declare module "next" {
|
||||
export interface NextApiRequest extends IncomingMessage {
|
||||
userId: number;
|
||||
body: any;
|
||||
query: { [key: string]: string | string[] };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,21 +20,21 @@ export const dateNotInPast = function (date: Date) {
|
|||
};
|
||||
|
||||
// This verifies the apiKey and sets the user if it is valid.
|
||||
export const verifyApiKey: NextMiddleware = async ({ query: { apiKey }, ...req }, res, next) => {
|
||||
if (!apiKey) return res.status(401).json({ message: "No apiKey provided" });
|
||||
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
|
||||
if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey provided" });
|
||||
// We remove the prefix from the user provided api_key. If no env set default to "cal_"
|
||||
const strippedApiKey = `${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.
|
||||
const hashedKey = hashAPIKey(strippedApiKey);
|
||||
// Check if the hashed api key exists in database.
|
||||
const validApiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
||||
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
||||
// If we cannot find any api key. Throw a 401 Unauthorized.
|
||||
if (!validApiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
||||
if (validApiKey.expiresAt && dateNotInPast(validApiKey.expiresAt)) {
|
||||
if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
||||
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
|
||||
return res.status(401).json({ error: "This apiKey is expired" });
|
||||
}
|
||||
if (!validApiKey.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 */
|
||||
req.userId = validApiKey.userId;
|
||||
req.userId = apiKey.userId;
|
||||
await next();
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// https://www.npmjs.com/package/next-transpile-modules
|
||||
// This makes our @calcom/prisma package from the monorepo to be transpiled and usable by API
|
||||
const withTM = require("next-transpile-modules")([
|
||||
"@calcom/app-store",
|
||||
"@calcom/prisma",
|
||||
|
@ -5,37 +7,31 @@ const withTM = require("next-transpile-modules")([
|
|||
"@calcom/ee",
|
||||
]);
|
||||
|
||||
// use something like withPlugins([withTM], {}) if more plugins added later.
|
||||
|
||||
module.exports = withTM({
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
// @note: disabling CORS matching all API routes as this will be a our Public API
|
||||
source: "/api/:path*",
|
||||
headers: [
|
||||
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||
{ key: "Access-Control-Allow-Origin", value: "*" },
|
||||
{ key: "Access-Control-Allow-Methods", value: "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
|
||||
{
|
||||
key: "Access-Control-Allow-Headers",
|
||||
value:
|
||||
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Content-Type, api_key, Authorization",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
// @note: redirects requests from: "/:rest*" the root level to the "/api/:rest*" folder by default.
|
||||
{
|
||||
source: "/:rest*",
|
||||
destination: "/api/:rest*",
|
||||
},
|
||||
// @note: redirects requests from api/v*/:rest to /api/:rest?version=* passing version as a query parameter.
|
||||
{
|
||||
source: "/api/v:version/:rest*",
|
||||
destination: "/api/:rest*?version=:version",
|
||||
},
|
||||
];
|
||||
return {
|
||||
beforeFiles: [
|
||||
// This redirects requests recieved at / the root to the /api/ folder.
|
||||
{
|
||||
source: "/v:version/:rest*",
|
||||
destination: "/api/v:version/:rest*",
|
||||
},
|
||||
// This redirects requests to api/v*/ to /api/ passing version as a query parameter.
|
||||
{
|
||||
source: "/api/v:version/:rest*",
|
||||
destination: "/api/:rest*?version=:version",
|
||||
},
|
||||
],
|
||||
fallback: [
|
||||
// These rewrites are checked after both pages/public files
|
||||
// and dynamic routes are checked
|
||||
{
|
||||
source: "/:path*",
|
||||
destination: `/api/:path*`,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue