Feature/wrap logging * feat: change all logging to go through our own logger function so that we can control log levels * move packages/trpc to using our own logger * merge Approved-by: Linus Flood
143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
import * as Sentry from "@sentry/nextjs"
|
|
import { type NextMiddleware, NextResponse } from "next/server"
|
|
|
|
import { Lang } from "@scandic-hotels/common/constants/language"
|
|
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 currentWebLogin from "@/middlewares/currentWebLogin"
|
|
import * as currentWebLoginEmail from "@/middlewares/currentWebLoginEmail"
|
|
import * as currentWebLogout from "@/middlewares/currentWebLogout"
|
|
import * as dateQueryParams from "@/middlewares/dateQueryParams"
|
|
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 legacySearchParams from "@/middlewares/legacySearchParams"
|
|
import * as myPages from "@/middlewares/myPages"
|
|
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)
|
|
|
|
if (!lang) {
|
|
// Lang is required for all our middleware.
|
|
// Without it we shortcircuit early.
|
|
// We use middleware-error route because notFound() requires a root layout
|
|
// which we do not want. We can move to that once all Current stuff is gone.
|
|
|
|
// Default to English if no lang is found.
|
|
headers.set("x-lang", Lang.en)
|
|
return NextResponse.rewrite(
|
|
new URL(`/${Lang.en}/middleware-error/404`, request.nextUrl),
|
|
{
|
|
request: {
|
|
headers,
|
|
},
|
|
status: 404,
|
|
statusText: "Not found",
|
|
}
|
|
)
|
|
}
|
|
|
|
// Note that the order of middlewares is important since that is the order they are matched by.
|
|
const middlewares = [
|
|
invalidUrl,
|
|
trailingSlash,
|
|
currentWebLogin,
|
|
currentWebLoginEmail,
|
|
currentWebLogout,
|
|
authRequired,
|
|
handleAuth,
|
|
handleDTMC,
|
|
myPages,
|
|
webView,
|
|
dateQueryParams,
|
|
legacySearchParams,
|
|
bookingFlow,
|
|
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).*)"],
|
|
}
|