import * as Sentry from "@sentry/nextjs" import { type NextMiddleware, NextResponse } from "next/server" import { logger } from "@scandic-hotels/common/logger" import { findLang } from "@scandic-hotels/common/utils/languages" import * as authRequired from "@/middlewares/authRequired" import * as bookingFlow from "@/middlewares/bookingFlow" import * as cmsContent from "@/middlewares/cmsContent" import * as dateQueryParams from "@/middlewares/dateQueryParams" import * as errorPages from "@/middlewares/errorPages" import * as familyAndFriends from "@/middlewares/familyAndFriends" import * as handleAuth from "@/middlewares/handleAuth" import * as handleDTMC from "@/middlewares/handleDTMC" import * as invalidUrl from "@/middlewares/invalidUrl" import * as languageRedirect from "@/middlewares/languageRedirect" import * as legacySearchParams from "@/middlewares/legacySearchParams" import * as myPages from "@/middlewares/myPages" import * as noValidLang from "@/middlewares/noValidLang" import * as redirect from "@/middlewares/redirect" import * as sasXScandic from "@/middlewares/sasXScandic" import * as trailingSlash from "@/middlewares/trailingSlash" import { getDefaultRequestHeaders } from "@/middlewares/utils" import * as webView from "@/middlewares/webView" export const middleware: NextMiddleware = async (request, event) => { // auth() overrides the request origin, we need the original for internal rewrites // @see getInternalNextURL() request.headers.set("x-sh-origin", request.nextUrl.origin) const headers = getDefaultRequestHeaders(request) const lang = findLang(request.nextUrl.pathname) // Note that the order of middlewares is important since that is the order they are matched by. const middlewares = [ languageRedirect, noValidLang, invalidUrl, trailingSlash, authRequired, handleAuth, handleDTMC, myPages, webView, dateQueryParams, legacySearchParams, bookingFlow, errorPages, familyAndFriends, sasXScandic, cmsContent, redirect, ] try { for (let i = 0; i < middlewares.length; ++i) { const middleware = middlewares[i] if (middleware.matcher(request)) { const result = await middleware.middleware(request, event) const _continue = result?.headers.get("x-continue") if (_continue) { continue } // Clean up internal headers result?.headers.delete("x-sh-origin") return result } } } catch (e) { if (e instanceof NextResponse && e.status) { const cause = await e.json() logger.error(`NextResponse Error in middleware`, cause) Sentry.captureException(cause) return NextResponse.rewrite( new URL(`/${lang}/middleware-error/${e.status}`, request.nextUrl), { request: { headers, }, status: e.status, statusText: e.statusText, } ) } logger.error(`Error in middleware`, e) Sentry.captureException(e) return NextResponse.rewrite( new URL(`/${lang}/middleware-error/500`, request.nextUrl), { request: { headers, }, status: 500, statusText: "Internal Server Error", } ) } // Follow through with normal App router rules. return NextResponse.next({ request: { headers, }, }) } // See "Matching Paths" below to learn more export const config = { /** * Copied from Clerk to protect all routes by default and handle * public routes inside middleware. * (https://clerk.com/docs/quickstarts/nextjs?utm_source=sponsorship&utm_medium=youtube&utm_campaign=code-with-antonio&utm_content=12-31-2023#add-authentication-to-your-app) */ matcher: ["/((?!.+\\.[\\w]+$|_next|_static|.netlify|api|trpc|sitemap).*)"], }