Openstatus
www.openstatus.dev
1import { NextResponse } from "next/server";
2
3import { auth } from "@/lib/auth";
4
5import { db, eq } from "@openstatus/db";
6import { user, usersToWorkspaces, workspace } from "@openstatus/db/src/schema";
7import { getCurrency } from "@openstatus/db/src/schema/plan/utils";
8
9export default auth(async (req) => {
10 const url = req.nextUrl.clone();
11 const response = NextResponse.next();
12
13 const continent = req.headers.get("x-vercel-ip-continent") || "NA";
14 const country = req.headers.get("x-vercel-ip-country") || "US";
15 const currency = getCurrency({ continent, country });
16
17 // NOTE: used in the pricing table to display the currency based on user's location
18 response.cookies.set("x-currency", currency);
19
20 if (url.pathname.includes("api/trpc")) {
21 return response;
22 }
23
24 if (!req.auth && url.pathname !== "/login") {
25 const newURL = new URL("/login", req.url);
26 const encodedSearchParams = `${url.pathname}${url.search}`;
27
28 if (encodedSearchParams) {
29 newURL.searchParams.append("redirectTo", encodedSearchParams);
30 }
31
32 return NextResponse.redirect(newURL);
33 }
34
35 const hasWorkspaceSlug = req.cookies.has("workspace-slug");
36
37 if (req.auth?.user?.id && !hasWorkspaceSlug) {
38 const [query] = await db
39 .select()
40 .from(usersToWorkspaces)
41 .innerJoin(user, eq(user.id, usersToWorkspaces.userId))
42 .innerJoin(workspace, eq(workspace.id, usersToWorkspaces.workspaceId))
43 .where(eq(user.id, Number.parseInt(req.auth.user.id)))
44 .all();
45
46 if (!query) {
47 console.error(">> Should not happen, no workspace found for user");
48 }
49
50 response.cookies.set("workspace-slug", query.workspace.slug);
51 }
52
53 if (!req.auth && hasWorkspaceSlug) {
54 response.cookies.delete("workspace-slug");
55 }
56
57 return response;
58});
59
60export const config = {
61 matcher: [
62 "/((?!api|assets|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
63 ],
64};