feat: return x-vercel-ip-timezone in headers (#6849)

* feat: add trpc to matcher and pass vercel timezone header

* feat: pass request to context

* feat: return timezone in header

* refactor: split context

* fix: remove tsignore comment

* Update [trpc].ts

---------

Co-authored-by: zomars <zomars@me.com>
This commit is contained in:
Nafees Nazik
2023-02-09 01:12:45 +00:00
committed by GitHub
co-authored by zomars
parent 05c33bd94b
commit f0db97bbb1
3 changed files with 59 additions and 19 deletions
+11
View File
@@ -59,6 +59,16 @@ const middleware: NextMiddleware = async (req) => {
return NextResponse.rewrite(url);
}
if (url.pathname.startsWith("/api/trpc/")) {
const requestHeaders = new Headers(req.headers);
requestHeaders.set("x-cal-timezone", req.headers.get("x-vercel-ip-timezone") ?? "");
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
}
if (url.pathname.startsWith("/auth/login")) {
const moreHeaders = new Headers(req.headers);
// Use this header to actually enforce CSP, otherwise it is running in Report Only mode on all pages.
@@ -79,6 +89,7 @@ export const config = {
"/api/auth/:path*",
"/apps/routing_forms/:path*",
"/:path*/embed",
"/api/trpc/:path*",
"/auth/login",
],
};
+18 -12
View File
@@ -1,6 +1,8 @@
/**
* This file contains tRPC's HTTP response handler
*/
import { z } from "zod";
import * as trpcNext from "@calcom/trpc/server/adapters/next";
import { createContext } from "@calcom/trpc/server/createContext";
import { appRouter } from "@calcom/trpc/server/routers/_app";
@@ -35,29 +37,35 @@ export default trpcNext.createNextApiHandler({
const TWO_HOURS_IN_SECONDS = 60 * 60 * 2;
// Our response to indicate no caching
const noCacheResponse = {};
const defaultHeaders: Record<"headers", Record<string, string>> = {
headers: {},
};
if (!!ctx?.req) {
const timezone = z.string().safeParse(ctx.req.headers["x-vercel-ip-timezone"]);
if (timezone.success) defaultHeaders.headers["x-cal-timezone"] = timezone.data;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ctx.req is available for SSR but not SSG
const isSSR = !!ctx?.req;
if (isSSR) {
return noCacheResponse;
if (!!ctx?.req) {
return defaultHeaders;
}
// No caching if we have a non-public path
// Assuming we have all our public routes in `viewer.public`
if (!paths || !paths.every((path) => path.startsWith("viewer.public."))) {
return noCacheResponse;
return defaultHeaders;
}
// No caching if we have any procedures errored
if (errors.length !== 0) {
return noCacheResponse;
return defaultHeaders;
}
// Never cache non-queries (aka mutations)
if (type !== "query") {
return noCacheResponse;
return defaultHeaders;
}
// cache request for 1 day + revalidate once every 5 seconds
@@ -77,11 +85,9 @@ export default trpcNext.createNextApiHandler({
// Get the cache value of the matching element, if any
if (matchedPath) cacheValue = cacheRules[matchedPath];
if (cacheValue) defaultHeaders.headers["Cache-Control"] = cacheValue;
// Finally we respond with our resolved cache value
return {
headers: {
"Cache-Control": cacheValue,
},
};
return defaultHeaders;
},
});