From 883aa2aa9b7686ebc9fcc0308ab7043501dd06a2 Mon Sep 17 00:00:00 2001 From: pheralb Date: Sat, 30 Mar 2024 12:27:01 +0000 Subject: [PATCH] Refactor API URL route and middleware, add Prisma errors --- src/app/api/url/route.ts | 75 ++++++++++++++++++++++------------------ src/middleware.ts | 39 ++++++++++++--------- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/app/api/url/route.ts b/src/app/api/url/route.ts index 54ed0fe..4f5de50 100644 --- a/src/app/api/url/route.ts +++ b/src/app/api/url/route.ts @@ -1,10 +1,10 @@ -import type { NextRequest } from "next/server"; - +import { Prisma } from "@prisma/client"; import { NextResponse } from "next/server"; import { db } from "@/server/db"; -export const GET = async (req: NextRequest) => { - const params = req.nextUrl.searchParams.get("slug"); +export const GET = async (req: Request) => { + const url = new URL(req.url); + const params = url.searchParams.get("slug"); const newHeaders = new Headers(req.headers); // If no slug provided (500): @@ -15,38 +15,45 @@ export const GET = async (req: NextRequest) => { ); } - // Search for the slug in the database: - const getLinkFromServer = await db.links.findUnique({ - where: { - slug: params, - }, - }); + try { + const getLinkFromServer = await db.links.findUnique({ + where: { + slug: params, + }, + }); + + if (!getLinkFromServer) { + return NextResponse.json( + { error: "Error: Slug not found or invalid." }, + { status: 404 }, + ); + } + + await db.links.update({ + where: { + id: getLinkFromServer.id, + }, + data: { + clicks: { + increment: 1, + }, + }, + }); + + newHeaders.set("cache-control", "public, max-age=31536000, immutable"); - // If no link found (404): - if (!getLinkFromServer) { return NextResponse.json( - { error: "Error: Slug not found or invalid." }, - { status: 404 }, + { message: "Link already exists.", url: getLinkFromServer.url }, + { headers: newHeaders, status: 200 }, + ); + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + console.log(`🚧 Error: ${error.message}`); + return NextResponse.json({ message: error.message }, { status: 400 }); + } + return NextResponse.json( + { message: "Something went wrong." }, + { status: 500 }, ); } - - // Increment the clicks in the database: - await db.links.update({ - where: { - id: getLinkFromServer.id, - }, - data: { - clicks: { - increment: 1, - }, - }, - }); - - // Cache: - newHeaders.set("cache-control", "public, max-age=31536000, immutable"); - - // Redirect to the URL: - return NextResponse.json(getLinkFromServer, { - headers: newHeaders, - }); }; diff --git a/src/middleware.ts b/src/middleware.ts index dc0a27e..105620b 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,6 +1,8 @@ import NextAuth from "next-auth"; import authConfig from "@/auth.config"; +import { NextResponse } from "next/server"; + import { DEFAULT_LOGIN_REDIRECT_URL, apiAuthPrefix, @@ -33,14 +35,16 @@ export default auth(async (req) => { // ⚙️ Is Auth Route. First, check is authenticated: if (isAuthRoute) { if (isLoggedIn) { - return Response.redirect(new URL(DEFAULT_LOGIN_REDIRECT_URL, nextUrl)); + return NextResponse.redirect( + new URL(DEFAULT_LOGIN_REDIRECT_URL, nextUrl), + ); } return; } // ⚙️ If Slug contains ``c``, redirect to /check/:slug: if (slugRoute && slugRoute.endsWith("&c")) { - return Response.redirect( + return NextResponse.redirect( new URL(`/check/${slugRoute.replace("&c", "")}`, nextUrl), ); } @@ -52,7 +56,7 @@ export default auth(async (req) => { callbackUrl += nextUrl.search; } const encodedCallbackUrl = encodeURIComponent(callbackUrl); - return Response.redirect( + return NextResponse.redirect( new URL(`/auth?callbackUrl=${encodedCallbackUrl}`, nextUrl), ); } @@ -60,21 +64,24 @@ export default auth(async (req) => { // ⚙️ Redirect using slug: // If not public route and not protected route: if (!isPublicRoute && !isProtectedRoute && !isCheckRoute) { - const data = await fetch(`${req.nextUrl.origin}/api/url?slug=${slugRoute}`); - - if (data.status === 404) { - return; - } - - const dataToJson = await data.json(); - - if (dataToJson.url) { - return Response.redirect(new URL(dataToJson.url as string).toString()); + try { + const getDataApi = await fetch( + `${req.nextUrl.origin}/api/url?slug=${slugRoute}`, + ); + + if (getDataApi.status === 404) { + return; + } + + const getDataUrl = await getDataApi.json(); + + if (getDataUrl?.url) { + return NextResponse.redirect(new URL(getDataUrl.url as string)); + } + } catch (error) { + console.error("🚧 Error fetching slug: ", error); } - - return; } - return; });