Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Commit

Permalink
move premium check to middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrykulakovfrontend committed Nov 7, 2023
1 parent b257fc2 commit 14b4d07
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 62 deletions.
52 changes: 30 additions & 22 deletions middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,51 @@ export const config = {
};

export async function middleware(req) {
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 reqPathName = req.nextUrl.pathname;

// 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) {
// 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();
}

12 changes: 2 additions & 10 deletions pages/account/statistics/link/[id].js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -75,8 +67,8 @@ export default function Statistics({ data }) {
)}

{data.stats.length > 0 && (
<div className="border mb-6 dark:border-primary-medium">
<div className="border-b border-primary-low bg-white dark:bg-primary-high dark:border-primary-medium px-4 py-5 mb-2 sm:px-6">
<div className="mb-6 border dark:border-primary-medium">
<div className="px-4 py-5 mb-2 bg-white border-b border-primary-low dark:bg-primary-high dark:border-primary-medium sm:px-6">
<h3 className="text-lg font-medium leading-6 text-primary-high">
Link clicks for {data.url}
</h3>
Expand Down
17 changes: 4 additions & 13 deletions pages/account/statistics/locations.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ 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);
if (status !== 200) {
Expand All @@ -50,7 +41,7 @@ export async function getServerSideProps(context) {
stats = Object.keys(profile.stats.countries)
.map((country) => ({
country,
value: profile.stats.countries[country],
value: profile.stats.countries[ country ],
}))
.sort((a, b) => b.value - a.value);
}
Expand Down Expand Up @@ -99,14 +90,14 @@ export default function Locations({ stats }) {
</th>
</tr>
</thead>
<tbody className="divide-y divide-primary-low dark:divide-primary-medium bg-white dark:bg-primary-high">
<tbody className="bg-white divide-y divide-primary-low dark:divide-primary-medium dark:bg-primary-high">
{stats &&
stats.map((item) => (
<tr key={item.country}>
<td className="md:whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-primary-high dark:text-primary-low sm:pl-6">
<td className="py-4 pl-4 pr-3 text-sm font-medium md:whitespace-nowrap text-primary-high dark:text-primary-low sm:pl-6">
{item.country}
</td>
<td className="whitespace-nowrap px-3 py-4 text-sm text-primary-medium dark:text-primary-low">
<td className="px-3 py-4 text-sm whitespace-nowrap text-primary-medium dark:text-primary-low">
{abbreviateNumber(item.value)}
</td>
</tr>
Expand Down
17 changes: 4 additions & 13 deletions pages/account/statistics/referers.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ 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);
if (status !== 200) {
Expand All @@ -50,7 +41,7 @@ export async function getServerSideProps(context) {
stats = Object.keys(profile.stats.referers)
.map((referer) => ({
referer,
value: profile.stats.referers[referer],
value: profile.stats.referers[ referer ],
}))
.sort((a, b) => b.value - a.value);
}
Expand Down Expand Up @@ -99,14 +90,14 @@ export default function Locations({ stats }) {
</th>
</tr>
</thead>
<tbody className="divide-y divide-primary-low dark:divide-primary-medium bg-white dark:bg-primary-high">
<tbody className="bg-white divide-y divide-primary-low dark:divide-primary-medium dark:bg-primary-high">
{stats &&
stats.map((item) => (
<tr key={item.referer}>
<td className="md:whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-primary-high dark:text-primary-low sm:pl-6">
<td className="py-4 pl-4 pr-3 text-sm font-medium md:whitespace-nowrap text-primary-high dark:text-primary-low sm:pl-6">
{item.referer.replaceAll("|", ".")}
</td>
<td className="whitespace-nowrap px-3 py-4 text-sm text-primary-medium dark:text-primary-low">
<td className="px-3 py-4 text-sm whitespace-nowrap text-primary-medium dark:text-primary-low">
{abbreviateNumber(item.value)}
</td>
</tr>
Expand Down
14 changes: 10 additions & 4 deletions pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ export const authOptions = {
token.id = profile.id;
token.username = profile.login;
}
const user = await User.findOne({ _id: token.sub });
if (user) {
token.accountType = user.type;
} else {
token.accountType = "free";
}
return token;
},
async session({ session, token }) {
Expand Down Expand Up @@ -122,13 +128,13 @@ export const authOptions = {
upsert: true,
},
);
const link = await Link.create([defaultLink(profile._id)], {
const link = await Link.create([ defaultLink(profile._id) ], {
new: true,
});
profile = await Profile.findOneAndUpdate(
{ username },
{
$push: { links: new ObjectId(link[0]._id) },
$push: { links: new ObjectId(link[ 0 ]._id) },
},
{ new: true },
);
Expand Down Expand Up @@ -159,13 +165,13 @@ export const authOptions = {
// add github link to profile if no links exist
if (profile.links.length === 0) {
logger.info("no links found for: ", username);
const link = await Link.create([defaultLink(profile._id)], {
const link = await Link.create([ defaultLink(profile._id) ], {
new: true,
});
await Profile.findOneAndUpdate(
{ username },
{
$push: { links: new ObjectId(link[0]._id) },
$push: { links: new ObjectId(link[ 0 ]._id) },
},
);
}
Expand Down

0 comments on commit 14b4d07

Please sign in to comment.