diff --git a/middleware.js b/middleware.js index a3b20e7a170..6a1a0545218 100644 --- a/middleware.js +++ b/middleware.js @@ -21,24 +21,31 @@ export async function middleware(req) { const protocol = process.env.NODE_ENV === "development" ? "http" : "https"; const hostname = req.headers.get("host"); const reqPathName = req.nextUrl.pathname; - const sessionRequired = ["/account", "/api/account"]; - const adminRequired = ["/admin", "/api/admin"]; + const adminRequired = [ "/admin", "/api/admin" ]; + // Trailing slash is necessary to catch URL /account/statistics/* but not index page + const premiumRequired = [ "/account/statistics/" ]; const adminUsers = process.env.ADMIN_USERS.split(","); const hostedDomain = process.env.NEXT_PUBLIC_BASE_URL.replace( /http:\/\/|https:\/\//, "", ); - const hostedDomains = [hostedDomain, `www.${hostedDomain}`]; - + const hostedDomains = [ hostedDomain, `www.${hostedDomain}` ]; + const sessionRequired = [ "/account", "/api/account" ]; + if ( + !sessionRequired + .concat(adminRequired) + .some((path) => reqPathName.startsWith(path)) + ) { + return NextResponse.next(); + } // if custom domain + on root path if (!hostedDomains.includes(hostname) && reqPathName === "/") { console.log(`custom domain used: "${hostname}"`); let res; let profile; - let url = `${ - process.env.NEXT_PUBLIC_BASE_URL - }/api/search/${encodeURIComponent(hostname)}`; + let url = `${process.env.NEXT_PUBLIC_BASE_URL + }/api/search/${encodeURIComponent(hostname)}`; try { res = await fetch(url, { method: "GET", @@ -73,38 +80,44 @@ export async function middleware(req) { console.error(`custom domain NOT matched "${hostname}"`); } - // if not in sessionRequired or adminRequired, skip - if ( - !sessionRequired - .concat(adminRequired) - .some((path) => reqPathName.startsWith(path)) - ) { - return NextResponse.next(); - } - - const session = await getToken({ + // Check token existence or validity + const token = await getToken({ req: req, secret: process.env.NEXTAUTH_SECRET, }); - // if no session reject request - if (!session) { + console.log(token) + + // if no token reject request + if (!token) { if (reqPathName.startsWith("/api")) { return NextResponse.json({}, { status: 401 }); } return NextResponse.redirect(new URL("/auth/signin", req.url)); } - const username = session.username; - // if admin request check user is allowed - if (adminRequired.some((path) => reqPathName.startsWith(path))) { - if (!adminUsers.includes(username)) { - if (reqPathName.startsWith("/api")) { - return NextResponse.json({}, { status: 401 }); - } - return NextResponse.redirect(new URL("/404", req.url)); + // Premium path + const isPremiumRoute = premiumRequired.some((path) => reqPathName.startsWith(path)) + const isUserPremium = token.accountType === "premium" + if (isPremiumRoute && !isUserPremium) { + if (reqPathName.startsWith("/api")) { + return NextResponse.json({}, { status: 401 }); + } + return NextResponse.redirect(new URL("/pricing", req.url)) + } + + // Admin Path + const username = token.username; + const isAdminRoute = adminRequired.some((path) => reqPathName.startsWith(path)) + const isUserAdmin = adminUsers.includes(username) + if (isAdminRoute && !isUserAdmin) { + if (reqPathName.startsWith("/api")) { + return NextResponse.json({}, { status: 401 }); } + return NextResponse.redirect(new URL("/404", req.url)); } + // Allow request return NextResponse.next(); } + diff --git a/pages/account/statistics/link/[id].js b/pages/account/statistics/link/[id].js index a15c95dbe1f..d2e8ed73df4 100644 --- a/pages/account/statistics/link/[id].js +++ b/pages/account/statistics/link/[id].js @@ -19,14 +19,6 @@ const DynamicChart = dynamic( export async function getServerSideProps(context) { const { req, res } = context; const session = await getServerSession(req, res, authOptions); - if (session.accountType !== "premium") { - return { - redirect: { - destination: "/account/onboarding", - permanent: false, - }, - }; - } const username = session.username; const { status, profile } = await getUserApi(req, res, username); @@ -75,8 +67,8 @@ export default function Statistics({ data }) { )} {data.stats.length > 0 && ( -