initial layout
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
|
||||
import { pingServer, verifyToken } from "@shared/api/server"
|
||||
import { ENTRY_PATHS_REGEXP, EXCLUDE_PATHS_REGEXP } from "@shared/lib/constants"
|
||||
|
||||
const redirector = async ({
|
||||
pathname,
|
||||
queryString,
|
||||
headers,
|
||||
initialPath,
|
||||
endPath,
|
||||
origin,
|
||||
}: {
|
||||
initialPath: string
|
||||
endPath: string
|
||||
pathname: string
|
||||
queryString: string
|
||||
origin: string
|
||||
headers: Headers
|
||||
}) => {
|
||||
if (pathname.includes(initialPath)) {
|
||||
const sp = queryString.length ? `?${queryString}` : ""
|
||||
const finalURL = `${origin}${pathname.replace(initialPath, endPath)}${sp}`
|
||||
return NextResponse.redirect(finalURL, { headers })
|
||||
}
|
||||
}
|
||||
|
||||
const redirections: { from: string; to: string }[] = []
|
||||
|
||||
export async function proxy(req: NextRequest) {
|
||||
// Base URL data from nextjs
|
||||
const { origin, pathname, searchParams } = req.nextUrl
|
||||
// Headers data from nextjs
|
||||
const headers = new Headers(req.headers)
|
||||
// Token data from cookies
|
||||
const token = req.cookies.get("access_token")?.value
|
||||
// Server status check
|
||||
const isServerAlive = (await pingServer()) !== false
|
||||
// Entry paths checkers
|
||||
const isEntryPath = ENTRY_PATHS_REGEXP.test(pathname)
|
||||
const isExcludedPath = EXCLUDE_PATHS_REGEXP.test(pathname)
|
||||
// Stringified qs
|
||||
const queryParams = searchParams.toString()
|
||||
|
||||
// Set current path header for analytics purposes
|
||||
headers.set("x-current-path", req.nextUrl.pathname)
|
||||
|
||||
// Redirect to under_maintenance if server is down
|
||||
if (!isServerAlive && pathname !== "/under_maintenance") {
|
||||
return NextResponse.redirect(
|
||||
`${origin}/under_maintenance?path=${pathname}${queryParams}`,
|
||||
{ headers },
|
||||
)
|
||||
}
|
||||
|
||||
// Verify user if page is not public
|
||||
if (!isExcludedPath && isServerAlive) {
|
||||
const isVerified =
|
||||
token &&
|
||||
(await verifyToken(token).catch((e) => {
|
||||
console.error(
|
||||
"Middleware verification error\n",
|
||||
String(e).toLowerCase(),
|
||||
)
|
||||
return null
|
||||
}))
|
||||
if (isVerified && isEntryPath) {
|
||||
return NextResponse.redirect(`${origin}/`, { headers })
|
||||
}
|
||||
if (!isVerified && !isEntryPath) {
|
||||
const returnParam = pathname === "/" ? "" : `?from=${pathname}`
|
||||
return NextResponse.redirect(`${origin}/login${returnParam}`, { headers })
|
||||
}
|
||||
}
|
||||
|
||||
for (const redirection of redirections) {
|
||||
const redirect = await redirector({
|
||||
pathname,
|
||||
headers,
|
||||
origin,
|
||||
initialPath: redirection.from,
|
||||
endPath: redirection.to,
|
||||
queryString: searchParams.toString(),
|
||||
})
|
||||
if (redirect) {
|
||||
return redirect
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.next({ headers, request: { headers } })
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
{
|
||||
source: "/((?!api|_next/static|_next/image|favicon.ico).*)",
|
||||
missing: [
|
||||
{ type: "header", key: "next-router-prefetch" },
|
||||
{ type: "header", key: "next-action" },
|
||||
{ type: "header", key: "purpose", value: "prefetch" },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user