Merge pull request #10 from calcom/feat/api-middleware

pull/9078/head
Agusti Fernandez 2022-03-29 02:28:27 +02:00 committed by GitHub
commit 411a3145d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 167 additions and 89 deletions

View File

@ -0,0 +1,9 @@
import { NextMiddleware } from "next-api-middleware";
import { nanoid } from "nanoid";
export const addRequestId: NextMiddleware = async (_req, res, next) => {
// Apply header
res.setHeader("X-Response-ID", nanoid());
// Let remaining middleware and API route execute
await next();
};

View File

@ -1,47 +0,0 @@
import { label, NextMiddleware } from "next-api-middleware";
import * as Sentry from "@sentry/nextjs";
import nanoid from "nanoid";
// 1 Create middleware functions
const captureErrors: NextMiddleware = async (req, res, next) => {
try {
// Catch any errors that are thrown in remaining
// middleware and the API route handler
await next();
} catch (err) {
const eventId = Sentry.captureException(err);
res.status(500);
res.json({ error: err });
}
};
const addRequestId: NextMiddleware = async (req, res, next) => {
// Let remaining middleware and API route execute
await next();
// Apply header
res.setHeader("X-Response-ID", nanoid());
};
// 2 Use `label` to assemble all middleware
const withMiddleware = label(
{
addRequestId,
sentry: captureErrors, // <-- Optionally alias middleware
},
["sentry"] // <-- Provide a list of middleware to call automatically
);
// 3 Define your API route handler
const apiRouteHandler = async (req, res) => {
res.status(200);
res.send("Hello world!");
};
// 4 Choose middleware to invoke for this API route
export default withMiddleware("addRequestId")(apiRouteHandler);

View File

@ -0,0 +1,16 @@
import { NextMiddleware } from "next-api-middleware";
import * as Sentry from "@sentry/nextjs";
export const captureErrors: NextMiddleware = async (_req, res, next) => {
try {
// Catch any errors that are thrown in remaining
// middleware and the API route handler
await next();
} catch (err) {
const eventId = Sentry.captureException(err);
console.log(eventId)
res.status(500);
res.json({ error: err });
}
};

View File

@ -1,36 +1,20 @@
// https://github.com/htunnicliff/next-api-middleware
// import prisma from "@calcom/prisma";
import { NextMiddleware } from "next-api-middleware";
// import { nanoid } from "nanoid";
import prisma from "@calcom/prisma";
// import { User } from "@calcom/prisma/client";
// import type { NextApiRequest, NextApiResponse } from "next";
const dateInPast = function (firstDate: Date, secondDate: Date) {
if (firstDate.setHours(0, 0, 0, 0) <= secondDate.setHours(0, 0, 0, 0)) {
return true;
}
}
const today = new Date();
// type ResponseData = {
// data?: User[];
// error?: unknown;
// };
// const dateInPast = function (firstDate: Date, secondDate: Date) {
// if (firstDate.setHours(0, 0, 0, 0) <= secondDate.setHours(0, 0, 0, 0)) {
// return true;
// }
// return false;
// };
// const today = new Date();
// export default async function user(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
// const apiKey = req.query.apiKey as string;
// const apiInDb = await prisma.apiKey.findUnique({ where: { id: apiKey } });
// if (!apiInDb) throw new Error('API key not found');
// const { expiresAt } = apiInDb;
// // if (!apiInDb) res.status(400).json({ error: 'Your api key is not valid' });
// if (expiresAt && dateInPast(expiresAt, today)) {
// try {
// const data = await prisma.user.findMany();
// res.status(200).json({ data });
// } catch (error) {
// // FIXME: Add zod for validation/error handling
// res.status(400).json({ error: error });
// }
// } else res.status(400).json({ error: 'Your api key is not valid' });
// }
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.apiKey as string } });
if (!apiKey) {
res.status(400).json({ error: 'Your api key is not valid' });
throw new Error('No api key found');
}
if (apiKey.expiresAt && dateInPast(apiKey.expiresAt, today)) await next();
else res.status(400).json({ error: 'Your api key is not valid' });
};

View File

@ -0,0 +1,15 @@
import { label } from "next-api-middleware";
import { addRequestId } from "./addRequestid";
import { captureErrors } from "./captureErrors";
import { verifyApiKey } from "./verifyApiKey";
const withMiddleware = label(
{
addRequestId,
verifyApiKey,
sentry: captureErrors, // <-- Optionally alias middleware
},
["sentry","verifyApiKey"] // <-- Provide a list of middleware to call automatically
);
export default withMiddleware;

View File

@ -31,6 +31,7 @@
"node-mocks-http": "^1.11.0"
},
"dependencies": {
"@sentry/nextjs": "^6.19.2",
"next": "^12.1.0",
"next-api-middleware": "^1.0.1",
"next-transpile-modules": "^9.0.0",

View File

@ -1,6 +1,7 @@
import prisma from "@calcom/prisma";
import { User } from "@calcom/prisma/client";
import withMiddleware from "@lib/helpers/withMiddleware";
import type { NextApiRequest, NextApiResponse } from "next";
type ResponseData = {
@ -8,8 +9,9 @@ type ResponseData = {
error?: unknown;
};
export default async function user(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
async function user(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const data = await prisma.user.findMany();
if (data) res.status(200).json({ data });
else res.status(400).json({ error: "No data found" });
}
export default withMiddleware("addRequestId")(user);

View File

@ -1,8 +1,8 @@
Arguments:
/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/bin/node /Users/ag/Library/Caches/fnm_multishells/3034_1648146693474/bin/yarn add --dev -W @typescript-eslint
/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/bin/node /Users/ag/Library/Caches/fnm_multishells/13639_1648391401808/bin/yarn add -W @types/next-api-middleware
PATH:
/Users/ag/Library/pnpm:/Users/ag/Library/Caches/fnm_multishells/3034_1648146693474/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/ag/.local/bin:/Users/ag/.fig/bin:/Users/ag/.local/bin:/Users/ag/.local/bin:/Users/ag/.yarn/bin
/Users/ag/Library/pnpm:/Users/ag/Library/Caches/fnm_multishells/13639_1648391401808/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/ag/.local/bin:/Users/ag/.fig/bin:/Users/ag/.local/bin:/Users/ag/.local/bin:/Users/ag/.yarn/bin
Yarn version:
1.22.17
@ -14,8 +14,8 @@ Platform:
darwin x64
Trace:
Error: https://registry.yarnpkg.com/@typescript-eslint: Request "https://registry.yarnpkg.com/@typescript-eslint" returned a 405
at Request.params.callback [as _callback] (/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/lib/node_modules/yarn/lib/cli.js:67038:18)
Error: https://registry.yarnpkg.com/@types%2fnext-api-middleware: Not found
at Request.params.callback [as _callback] (/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/lib/node_modules/yarn/lib/cli.js:67029:18)
at Request.self.callback (/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/lib/node_modules/yarn/lib/cli.js:140883:22)
at Request.emit (events.js:400:28)
at Request.<anonymous> (/Users/ag/Library/Application Support/fnm/node-versions/v14.17.6/installation/lib/node_modules/yarn/lib/cli.js:141855:10)
@ -53,15 +53,18 @@ npm manifest:
"@babel/preset-typescript": "^7.16.7",
"@calcom/prisma": "*",
"@calcom/tsconfig": "*",
"@typescript-eslint/eslint-plugin": "^5.16.0",
"babel-jest": "^27.5.1",
"husky": "^7.0.4",
"jest": "^27.5.1",
"node-mocks-http": "^1.11.0",
"typescript": "^4.6.3"
"node-mocks-http": "^1.11.0"
},
"dependencies": {
"next": "^12.1.0",
"next-api-middleware": "^1.0.1",
"next-transpile-modules": "^9.0.0",
"next-validations": "^0.1.11",
"typescript": "^4.6.3",
"zod": "^3.14.2"
}
}
@ -3614,6 +3617,11 @@ Lockfile:
jest-matcher-utils "^27.0.0"
pretty-format "^27.0.0"
"@types/json-schema@^7.0.9":
version "7.0.10"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.10.tgz#9b05b7896166cd00e9cbd59864853abf65d9ac23"
integrity sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@ -3886,6 +3894,21 @@ Lockfile:
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3"
integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==
"@typescript-eslint/eslint-plugin@^5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz#78f246dd8d1b528fc5bfca99a8a64d4023a3d86d"
integrity sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==
dependencies:
"@typescript-eslint/scope-manager" "5.16.0"
"@typescript-eslint/type-utils" "5.16.0"
"@typescript-eslint/utils" "5.16.0"
debug "^4.3.2"
functional-red-black-tree "^1.0.1"
ignore "^5.1.8"
regexpp "^3.2.0"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0":
version "5.14.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.14.0.tgz#7c79f898aa3cff0ceee6f1d34eeed0f034fb9ef3"
@ -3904,11 +3927,33 @@ Lockfile:
"@typescript-eslint/types" "5.14.0"
"@typescript-eslint/visitor-keys" "5.14.0"
"@typescript-eslint/scope-manager@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz#7e7909d64bd0c4d8aef629cdc764b9d3e1d3a69a"
integrity sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==
dependencies:
"@typescript-eslint/types" "5.16.0"
"@typescript-eslint/visitor-keys" "5.16.0"
"@typescript-eslint/type-utils@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz#b482bdde1d7d7c0c7080f7f2f67ea9580b9e0692"
integrity sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==
dependencies:
"@typescript-eslint/utils" "5.16.0"
debug "^4.3.2"
tsutils "^3.21.0"
"@typescript-eslint/types@5.14.0":
version "5.14.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.14.0.tgz#96317cf116cea4befabc0defef371a1013f8ab11"
integrity sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw==
"@typescript-eslint/types@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
"@typescript-eslint/typescript-estree@5.14.0":
version "5.14.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz#78b7f7385d5b6f2748aacea5c9b7f6ae62058314"
@ -3922,6 +3967,31 @@ Lockfile:
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
integrity sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==
dependencies:
"@typescript-eslint/types" "5.16.0"
"@typescript-eslint/visitor-keys" "5.16.0"
debug "^4.3.2"
globby "^11.0.4"
is-glob "^4.0.3"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.16.0.tgz#42218b459d6d66418a4eb199a382bdc261650679"
integrity sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.16.0"
"@typescript-eslint/types" "5.16.0"
"@typescript-eslint/typescript-estree" "5.16.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/visitor-keys@5.14.0":
version "5.14.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz#1927005b3434ccd0d3ae1b2ecf60e65943c36986"
@ -3930,6 +4000,14 @@ Lockfile:
"@typescript-eslint/types" "5.14.0"
eslint-visitor-keys "^3.0.0"
"@typescript-eslint/visitor-keys@5.16.0":
version "5.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
integrity sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==
dependencies:
"@typescript-eslint/types" "5.16.0"
eslint-visitor-keys "^3.0.0"
"@vercel/edge-functions-ui@^0.2.1":
version "0.2.1"
resolved "https://registry.yarnpkg.com/@vercel/edge-functions-ui/-/edge-functions-ui-0.2.1.tgz#8af0a5d8d4d544364fa79c4d075564e3a5bd972e"
@ -6383,6 +6461,14 @@ Lockfile:
semver "^6.3.0"
string.prototype.matchall "^4.0.6"
eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-scope@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
@ -6477,6 +6563,11 @@ Lockfile:
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
@ -7990,7 +8081,7 @@ Lockfile:
resolved "https://registry.yarnpkg.com/iframe-resizer/-/iframe-resizer-4.3.2.tgz#42dd88345d18b9e377b6044dddb98c664ab0ce6b"
integrity sha512-gOWo2hmdPjMQsQ+zTKbses08mDfDEMh4NneGQNP4qwePYujY1lguqP6gnbeJkf154gojWlBhIltlgnMfYjGHWA==
ignore@^5.2.0:
ignore@^5.1.8, ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
@ -11053,6 +11144,13 @@ Lockfile:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
next-api-middleware@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/next-api-middleware/-/next-api-middleware-1.0.1.tgz#8dd76abeace9e10c6be29c9c9486a84cb649cc12"
integrity sha512-t8UbZ9UUPFB7nklrHdAusn7MfoVSHtnWlRV1R0hirvLRHPDnzidTnw1Mu99Kqvc1bVC0rQSUX5kf0j/4nmEtfA==
dependencies:
debug "^4.3.2"
next-auth@^4.0.6:
version "4.3.0"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.3.0.tgz#93274254f9e6263c3c3edf7169a92fb13a700619"