From ef9f032366444a311c28bd4c9b9cfd8c82b93fc6 Mon Sep 17 00:00:00 2001 From: i701 Date: Fri, 28 Mar 2025 22:24:45 +0500 Subject: [PATCH] refactor: streamline authentication flow by removing unused code, replacing custom auth utilities with NextAuth, and updating session handling in components --- actions/auth-actions.ts | 47 ++++-- actions/omada-actions.ts | 31 ++-- app/(auth)/auth/signin/page.tsx | 4 - app/(dashboard)/devices/page.tsx | 15 +- components/auth/account-popver.tsx | 100 ++++++------ components/auth/application-layout.tsx | 21 +-- components/auth/verify-otp-form.tsx | 27 ++-- components/devices-table.tsx | 144 +++++++++-------- components/wallet.tsx | 210 ++++++++++++------------- lib/auth-utils.ts | 15 -- 10 files changed, 291 insertions(+), 323 deletions(-) delete mode 100644 lib/auth-utils.ts diff --git a/actions/auth-actions.ts b/actions/auth-actions.ts index 564de7b..9541682 100644 --- a/actions/auth-actions.ts +++ b/actions/auth-actions.ts @@ -10,6 +10,11 @@ const formSchema = z.object({ .regex(/^[7|9][0-9]{2}-[0-9]{4}$/, "Please enter a valid phone number"), }); +type FilterUserResponse = { + ok: boolean; + verified: boolean; +}; + export async function signin(previousState: ActionState, formData: FormData) { const phoneNumber = formData.get("phoneNumber") as string; const result = formSchema.safeParse({ phoneNumber }); @@ -31,7 +36,28 @@ export async function signin(previousState: ActionState, formData: FormData) { const FORMATTED_MOBILE_NUMBER: string = `${phoneNumber.split("-").join("")}`; console.log({ FORMATTED_MOBILE_NUMBER }); - const userExistsResponse = await fetch( + const user = await fetch( + `${process.env.SARLINK_API_BASE_URL}/api/auth/users/filter/?mobile=${FORMATTED_MOBILE_NUMBER}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }, + ); + const userData = (await user.json()) as FilterUserResponse; + if (!userData?.ok) { + return redirect(`/auth/signup?phone_number=${phoneNumber}`); + } + if (!userData.verified) { + return { + message: + "Your account is on pending verification. Please wait for a response from admin or contact shihaam.", + status: "error", + }; + } + + const sendOTPResponse = await fetch( `${process.env.SARLINK_API_BASE_URL}/auth/mobile/`, { method: "POST", @@ -43,23 +69,10 @@ export async function signin(previousState: ActionState, formData: FormData) { }), }, ); - const userExists = await userExistsResponse.json(); - console.log("user exists", userExists); - if (userExists?.non_field_errors) { - return redirect(`/signup?phone_number=${phoneNumber}`); - } + const otpResponse = await sendOTPResponse.json(); + console.log("otpResponse", otpResponse); - if (!userExists?.verified) - return { - message: - "Your account is on pending verification. Please wait for a response from admin or contact shihaam.", - status: "error", - }; - - // await authClient.phoneNumber.sendOtp({ - // phoneNumber: NUMBER_WITH_COUNTRY_CODE, - // }); - redirect(`/verify-otp?phone_number=${FORMATTED_MOBILE_NUMBER}`); + redirect(`/auth/verify-otp?phone_number=${FORMATTED_MOBILE_NUMBER}`); } type ActionState = { diff --git a/actions/omada-actions.ts b/actions/omada-actions.ts index 8f02359..4638677 100644 --- a/actions/omada-actions.ts +++ b/actions/omada-actions.ts @@ -1,6 +1,5 @@ "use server"; -import prisma from "@/lib/db"; import type { GroupProfile, MacAddress, OmadaResponse } from "@/lib/types"; import { formatMacAddress } from "@/lib/utils"; import { revalidatePath } from "next/cache"; @@ -124,11 +123,11 @@ export async function blockDevice({ if (!macAddress) { throw new Error("macAddress is a required parameter"); } - const device = await prisma.device.findFirst({ - where: { - mac: macAddress, - }, - }); + // const device = await prisma.device.findFirst({ + // where: { + // mac: macAddress, + // }, + // }); try { const baseUrl: string = process.env.OMADA_BASE_URL || ""; const url: string = `${baseUrl}/api/v2/sites/${process.env.OMADA_SITE_ID}/cmd/clients/${formatMacAddress(macAddress)}/${type}`; @@ -146,16 +145,16 @@ export async function blockDevice({ if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - await prisma.device.update({ - where: { - id: device?.id, - }, - data: { - reasonForBlocking: type === "block" ? reason : "", - blocked: type === "block", - blockedBy: blockedBy, - }, - }); + // await prisma.device.update({ + // where: { + // id: device?.id, + // }, + // data: { + // reasonForBlocking: type === "block" ? reason : "", + // blocked: type === "block", + // blockedBy: blockedBy, + // }, + // }); revalidatePath("/parental-control"); } catch (error) { console.error("Error blocking device:", error); diff --git a/app/(auth)/auth/signin/page.tsx b/app/(auth)/auth/signin/page.tsx index 1b9f7dd..51792f6 100644 --- a/app/(auth)/auth/signin/page.tsx +++ b/app/(auth)/auth/signin/page.tsx @@ -1,9 +1,5 @@ import LoginForm from "@/components/auth/login-form"; -import { auth } from "@/app/auth"; -import { headers } from "next/headers"; import Image from "next/image"; -import { redirect } from "next/navigation"; -import React from "react"; export default async function LoginPage() { return ( diff --git a/app/(dashboard)/devices/page.tsx b/app/(dashboard)/devices/page.tsx index 1161025..97500c8 100644 --- a/app/(dashboard)/devices/page.tsx +++ b/app/(dashboard)/devices/page.tsx @@ -1,12 +1,10 @@ +import { authOptions } from "@/app/auth"; import { DevicesTable } from "@/components/devices-table"; import Search from "@/components/search"; import AddDeviceDialogForm from "@/components/user/add-device-dialog"; -import { getCurrentUser } from "@/lib/auth-utils"; +import { getServerSession } from "next-auth"; import React, { Suspense } from "react"; - - - export default async function Devices({ searchParams, }: { @@ -18,14 +16,12 @@ export default async function Devices({ }>; }) { const query = (await searchParams)?.query || ""; - const user = await getCurrentUser() + const session = await getServerSession(authOptions); return (
-

- My Devices -

- +

My Devices

+
-
diff --git a/components/auth/account-popver.tsx b/components/auth/account-popver.tsx index 0349344..e55aa1e 100644 --- a/components/auth/account-popver.tsx +++ b/components/auth/account-popver.tsx @@ -1,56 +1,54 @@ -'use client' -import { Button } from "@/components/ui/button" +"use client"; +import { Button } from "@/components/ui/button"; import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover" -import { authClient } from "@/lib/auth-client"; -import { Loader2, User as UserIcon } from "lucide-react" -import { useRouter } from "next/navigation" -import { useState } from "react" + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Loader2, User as UserIcon } from "lucide-react"; +import { signOut, useSession } from "next-auth/react"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; export function AccountPopover() { - const session = authClient.useSession(); - const [loading, setLoading] = useState(false) - const router = useRouter() + const session = useSession(); + const [loading, setLoading] = useState(false); + const router = useRouter(); - if (session.isPending) { - - } - return ( - - - - - - -
-
-

{session.data?.user?.name}

-

- {session.data?.user?.phoneNumber} -

-
- -
-
-
- ) + if (session.status === "loading") { + ; + } + return ( + + + + + +
+
+

+ {session.data?.user?.name} +

+

+ {session.data?.user?.phoneNumber} +

+
+ +
+
+
+ ); } diff --git a/components/auth/application-layout.tsx b/components/auth/application-layout.tsx index f4bf083..8e0ca93 100644 --- a/components/auth/application-layout.tsx +++ b/components/auth/application-layout.tsx @@ -4,33 +4,26 @@ import { Wallet } from "@/components/wallet"; import { ModeToggle } from "@/components/theme-toggle"; import { AppSidebar } from "@/components/ui/app-sidebar"; +import { authOptions } from "@/app/auth"; import { Separator } from "@/components/ui/separator"; import { SidebarInset, SidebarProvider, SidebarTrigger, } from "@/components/ui/sidebar"; -import { auth } from "@/app/auth"; -import prisma from "@/lib/db"; +import { getServerSession } from "next-auth"; import { headers } from "next/headers"; import { AccountPopover } from "./account-popver"; export async function ApplicationLayout({ children, }: { children: React.ReactNode }) { - const session = await auth.api.getSession({ - headers: await headers(), - }); - const billFormula = await prisma.billFormula.findFirst(); - const user = await prisma.user.findFirst({ - where: { - id: session?.user?.id, - }, - }); + const session = await getServerSession(authOptions); + return ( - - + + {/* */}
@@ -44,7 +37,7 @@ export async function ApplicationLayout({
- + {/* */}
diff --git a/components/auth/verify-otp-form.tsx b/components/auth/verify-otp-form.tsx index c65d40e..529302f 100644 --- a/components/auth/verify-otp-form.tsx +++ b/components/auth/verify-otp-form.tsx @@ -3,7 +3,6 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; -import { authClient } from "@/lib/auth-client"; import { zodResolver } from "@hookform/resolvers/zod"; import { Loader2 } from "lucide-react"; import Link from "next/link"; @@ -37,16 +36,16 @@ export default function VerifyOTPForm({ const onSubmit: SubmitHandler> = (data) => { startTransition(async () => { - const isVerified = await authClient.phoneNumber.verify({ - phoneNumber: phone_number, - code: data.pin, - }); - console.log({ isVerified }); - if (!isVerified.error) { - router.push("/devices"); - } else { - toast.error(isVerified.error.message); - } + // const isVerified = await authClient.phoneNumber.verify({ + // phoneNumber: phone_number, + // code: data.pin, + // }); + // console.log({ isVerified }); + // if (!isVerified.error) { + // router.push("/devices"); + // } else { + // toast.error(isVerified.error.message); + // } }); }; @@ -70,11 +69,7 @@ export default function VerifyOTPForm({

{errors.pin.message}

)}
- diff --git a/components/devices-table.tsx b/components/devices-table.tsx index a93682f..3c84fec 100644 --- a/components/devices-table.tsx +++ b/components/devices-table.tsx @@ -1,3 +1,4 @@ +import { authOptions } from "@/app/auth"; import { Table, TableBody, @@ -8,9 +9,7 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import { auth } from "@/app/auth"; -import prisma from "@/lib/db"; -import { headers } from "next/headers"; +import { getServerSession } from "next-auth"; import ClickableRow from "./clickable-row"; import DeviceCard from "./device-card"; import Pagination from "./pagination"; @@ -26,85 +25,84 @@ export async function DevicesTable({ }>; parentalControl?: boolean; }) { - const session = await auth.api.getSession({ - headers: await headers(), - }); - const isAdmin = session?.user.role === "ADMIN"; + const session = await getServerSession(authOptions); + const isAdmin = session?.user; const query = (await searchParams)?.query || ""; const page = (await searchParams)?.page; const sortBy = (await searchParams)?.sortBy || "asc"; - const totalDevices = await prisma.device.count({ - where: { - userId: isAdmin ? undefined : session?.session.userId, - OR: [ - { - name: { - contains: query || "", - mode: "insensitive", - }, - }, - { - mac: { - contains: query || "", - mode: "insensitive", - }, - }, - ], - NOT: { - payments: { - some: { - paid: false, - }, - }, - }, - isActive: isAdmin ? undefined : parentalControl, - blocked: isAdmin - ? undefined - : parentalControl !== undefined - ? undefined - : false, - }, - }); + // const totalDevices = await prisma.device.count({ + // where: { + // userId: isAdmin ? undefined : session?.session.userId, + // OR: [ + // { + // name: { + // contains: query || "", + // mode: "insensitive", + // }, + // }, + // { + // mac: { + // contains: query || "", + // mode: "insensitive", + // }, + // }, + // ], + // NOT: { + // payments: { + // some: { + // paid: false, + // }, + // }, + // }, + // isActive: isAdmin ? undefined : parentalControl, + // blocked: isAdmin + // ? undefined + // : parentalControl !== undefined + // ? undefined + // : false, + // }, + // }); - const totalPages = Math.ceil(totalDevices / 10); + // const totalPages = Math.ceil(totalDevices / 10); const limit = 10; const offset = (Number(page) - 1) * limit || 0; - const devices = await prisma.device.findMany({ - where: { - userId: session?.session.userId, - OR: [ - { - name: { - contains: query || "", - mode: "insensitive", - }, - }, - { - mac: { - contains: query || "", - mode: "insensitive", - }, - }, - ], - NOT: { - payments: { - some: { - paid: false, - }, - }, - }, - isActive: parentalControl, - blocked: parentalControl !== undefined ? undefined : false, - }, + // const devices = await prisma.device.findMany({ + // where: { + // userId: session?.session.userId, + // OR: [ + // { + // name: { + // contains: query || "", + // mode: "insensitive", + // }, + // }, + // { + // mac: { + // contains: query || "", + // mode: "insensitive", + // }, + // }, + // ], + // NOT: { + // payments: { + // some: { + // paid: false, + // }, + // }, + // }, + // isActive: parentalControl, + // blocked: parentalControl !== undefined ? undefined : false, + // }, - skip: offset, - take: limit, - orderBy: { - name: `${sortBy}` as "asc" | "desc", - }, - }); + // skip: offset, + // take: limit, + // orderBy: { + // name: `${sortBy}` as "asc" | "desc", + // }, + // }); + return null; return (
{devices.length === 0 ? ( diff --git a/components/wallet.tsx b/components/wallet.tsx index e1672f2..ec3f798 100644 --- a/components/wallet.tsx +++ b/components/wallet.tsx @@ -2,123 +2,119 @@ import { Button } from "@/components/ui/button"; import { - Drawer, - DrawerClose, - DrawerContent, - DrawerDescription, - DrawerFooter, - DrawerHeader, - DrawerTitle, - DrawerTrigger, + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, } from "@/components/ui/drawer"; -import { - WalletDrawerOpenAtom, - walletTopUpValue, -} from "@/lib/atoms"; -import { authClient } from "@/lib/auth-client"; +import { WalletDrawerOpenAtom, walletTopUpValue } from "@/lib/atoms"; import type { TopupType } from "@/lib/types"; -import { useAtom, } from "jotai"; -import { - CircleDollarSign, - Loader2, - Wallet2, -} from "lucide-react"; -import { usePathname, } from "next/navigation"; +import { useAtom } from "jotai"; +import { CircleDollarSign, Loader2, Wallet2 } from "lucide-react"; +import { useSession } from "next-auth/react"; +import { usePathname } from "next/navigation"; import { useState } from "react"; import NumberInput from "./number-input"; - - export function Wallet({ - walletBalance, + walletBalance, }: { - walletBalance: number; + walletBalance: number; }) { - const session = authClient.useSession(); - const pathname = usePathname(); - const [amount, setAmount] = useAtom(walletTopUpValue); - const [isOpen, setIsOpen] = useAtom(WalletDrawerOpenAtom); - const [disabled, setDisabled] = useState(false); - // const router = useRouter(); + const session = useSession(); + const pathname = usePathname(); + const [amount, setAmount] = useAtom(walletTopUpValue); + const [isOpen, setIsOpen] = useAtom(WalletDrawerOpenAtom); + const [disabled, setDisabled] = useState(false); + // const router = useRouter(); - if (pathname === "/payment") { - return null; - } + if (pathname === "/payment") { + return null; + } - const data: TopupType = { - userId: session?.data?.user.id ?? "", - amount: Number.parseFloat(amount.toFixed(2)), - paid: false, - }; + const data: TopupType = { + userId: session?.data?.user.id ?? "", + amount: Number.parseFloat(amount.toFixed(2)), + paid: false, + }; - return ( - - - - - -
- - Wallet - -
- Your wallet balance is{" "} - - {new Intl.NumberFormat('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(walletBalance)} - {" "} -
-
-
+ return ( + + + + + +
+ + Wallet + +
+ Your wallet balance is{" "} + + {new Intl.NumberFormat("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }).format(walletBalance)} + {" "} +
+
+
-
- setAmount(value)} - maxAllowed={5000} - isDisabled={amount === 0} - /> - -
- - - - - - -
-
-
- ); +
+ setAmount(value)} + maxAllowed={5000} + isDisabled={amount === 0} + /> +
+ + + + + + +
+
+
+ ); } - diff --git a/lib/auth-utils.ts b/lib/auth-utils.ts deleted file mode 100644 index 78685d4..0000000 --- a/lib/auth-utils.ts +++ /dev/null @@ -1,15 +0,0 @@ -"use server"; -import { headers } from "next/headers"; -import { cache } from "react"; -import { auth } from "../app/auth"; - -const getCurrentUserCache = cache(async () => { - const session = await auth.api.getSession({ - headers: await headers(), - }); - return session?.user; -}); - -export async function getCurrentUser() { - return await getCurrentUserCache(); -}