mirror of
https://github.com/hanzoai/dataroom.git
synced 2026-10-30 18:41:07 +00:00
ioredis is replaced by @hanzo/kv, which is a fork of it — the module specifier
changes and the exported names follow: Redis is KV, RedisOptions is KVOptions.
Local identifiers and comments follow too, so nothing in the tree calls this
client by another product's name.
Third-party packages keep their own names, because they name themselves:
@socket.io/redis-adapter, connect-redis, rate-limit-redis. They take a client of
this shape and @hanzo/kv is that shape.
⚠️ Mechanical and unverified: no build or typecheck was run in this repo. Run
one before relying on it.
94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
|
|
|
|
import AppMiddleware from "@/lib/middleware/app";
|
|
|
|
import { BLOCKED_PATHNAMES } from "./lib/constants";
|
|
import IncomingWebhookMiddleware, {
|
|
isWebhookPath,
|
|
} from "./lib/middleware/incoming-webhooks";
|
|
import InsightsMiddleware from "./lib/middleware/insights";
|
|
|
|
function isAnalyticsPath(path: string) {
|
|
const pattern = /^\/ingest\/.*/;
|
|
return pattern.test(path);
|
|
}
|
|
|
|
// App domains that should NOT be treated as custom domains
|
|
const APP_DOMAINS = [
|
|
"localhost",
|
|
"dataroom.hanzo.ai",
|
|
"hanzo.ai",
|
|
".vercel.app",
|
|
];
|
|
|
|
function isCustomDomain(host: string) {
|
|
if (process.env.NODE_ENV === "development") {
|
|
return host?.includes(".local") || host?.includes("dataroom.hanzo.dev");
|
|
}
|
|
return !APP_DOMAINS.some((d) =>
|
|
d.startsWith(".") ? host?.endsWith(d) : host?.includes(d),
|
|
);
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
/*
|
|
* Match all paths except for:
|
|
* 1. /api/ routes
|
|
* 2. /_next/ (Next.js internals)
|
|
* 3. /_static (inside /public)
|
|
* 4. /_vercel (Vercel internals)
|
|
* 5. /favicon.ico, /sitemap.xml, /robots.txt (static files)
|
|
*/
|
|
"/((?!api/|_next/|_static|vendor|_icons|_vercel|favicon.ico|sitemap.xml|robots.txt).*)",
|
|
],
|
|
};
|
|
|
|
export default async function middleware(req: NextRequest, ev: NextFetchEvent) {
|
|
const path = req.nextUrl.pathname;
|
|
const host = req.headers.get("host");
|
|
|
|
if (isAnalyticsPath(path)) {
|
|
return InsightsMiddleware(req);
|
|
}
|
|
|
|
// Handle incoming webhooks
|
|
if (isWebhookPath(host)) {
|
|
return IncomingWebhookMiddleware(req);
|
|
}
|
|
|
|
// For custom domains, rewrite to domain viewer routes
|
|
// NOTE: DomainMiddleware is dynamically imported to avoid pulling @hanzo/kv
|
|
// into the Edge Runtime bundle (Edge Runtime has no TCP/net APIs)
|
|
if (isCustomDomain(host || "")) {
|
|
const { default: DomainMiddleware } = await import(
|
|
"@/lib/middleware/domain"
|
|
);
|
|
return DomainMiddleware(req);
|
|
}
|
|
|
|
// Handle standard app paths
|
|
if (
|
|
!path.startsWith("/view/") &&
|
|
!path.startsWith("/verify") &&
|
|
!path.startsWith("/unsubscribe") &&
|
|
!path.startsWith("/notification-preferences") &&
|
|
!path.startsWith("/auth/email")
|
|
) {
|
|
return AppMiddleware(req);
|
|
}
|
|
|
|
// Check for blocked pathnames in view routes
|
|
if (
|
|
path.startsWith("/view/") &&
|
|
(BLOCKED_PATHNAMES.some((blockedPath) => path.includes(blockedPath)) ||
|
|
path.includes("."))
|
|
) {
|
|
const url = req.nextUrl.clone();
|
|
url.pathname = "/404";
|
|
return NextResponse.rewrite(url, { status: 404 });
|
|
}
|
|
|
|
return NextResponse.next();
|
|
}
|