Added guard for unauthorized/authorized users
This commit is contained in:
parent
a5090d2cc3
commit
047e1f6fa9
|
|
@ -23,6 +23,7 @@
|
|||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"bcrypt": "^5.1.1",
|
||||
"client-only": "^0.0.1",
|
||||
"clsx": "^2.1.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"next": "14.1.0",
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ dependencies:
|
|||
bcrypt:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
client-only:
|
||||
specifier: ^0.0.1
|
||||
version: 0.0.1
|
||||
clsx:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
|
|
|
|||
14
src/app/(auth)/login/layout.tsx
Normal file
14
src/app/(auth)/login/layout.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
|
||||
import guestOnly from "@/features/auth/actions/guestOnly";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default async function LoginLayout({ children }: Props) {
|
||||
|
||||
await guestOnly()
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import getUser from "@/features/auth/actions/getUser";
|
||||
import signIn from "@/features/auth/actions/signIn";
|
||||
import {
|
||||
Paper,
|
||||
|
|
@ -12,7 +13,9 @@ import {
|
|||
Button,
|
||||
Alert,
|
||||
} from "@mantine/core";
|
||||
import React from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useFormState } from "react-dom";
|
||||
|
||||
const initialState = {
|
||||
|
|
|
|||
21
src/app/(auth)/logout/page.tsx
Normal file
21
src/app/(auth)/logout/page.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"use client"
|
||||
import getUser from "@//features/auth/actions/getUser";
|
||||
import logout from "@/features/auth/actions/logout";
|
||||
import { redirect } from "next/navigation";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
/**
|
||||
* LogoutPage component handles the logout process.
|
||||
* It checks if a user is logged in, logs them out, and redirects to the login page.
|
||||
*/
|
||||
export default function LogoutPage() {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const logoutAction = async () => await logout()
|
||||
|
||||
logoutAction()
|
||||
}, [])
|
||||
|
||||
return <div></div>;
|
||||
}
|
||||
14
src/app/(auth)/register/layout.tsx
Normal file
14
src/app/(auth)/register/layout.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
|
||||
import guestOnly from "@/features/auth/actions/guestOnly";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default async function RegisterLayout({ children }: Props) {
|
||||
|
||||
await guestOnly()
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
|
@ -13,9 +13,9 @@ interface Props {
|
|||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default function Layout(props: Props) {
|
||||
export default async function Layout(props: Props) {
|
||||
|
||||
const user = getUser()
|
||||
const user = await getUser()
|
||||
|
||||
if (!user){
|
||||
redirect("/login")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import logo from "@/assets/logos/logo-dsg.png";
|
|||
import cx from "clsx";
|
||||
import classNames from "./styles.module.css";
|
||||
import { TbChevronDown, TbLogout, TbSettings } from "react-icons/tb";
|
||||
import userMenuItems from "./_data/UserMenuItems";
|
||||
import userMenuItems from "./_data/userMenuItems";
|
||||
import UserMenuItem from "./_components/UserMenuItem/UserMenuItem";
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Menu, rem } from '@mantine/core'
|
||||
import React from 'react'
|
||||
import { UserMenuItem } from '../../_data/UserMenuItems'
|
||||
import { UserMenuItem } from '../../_data/userMenuItems'
|
||||
|
||||
interface Props {
|
||||
item: UserMenuItem
|
||||
|
|
@ -10,12 +10,14 @@ export default function UserMenuItem({item}: Props) {
|
|||
return (
|
||||
<Menu.Item
|
||||
color={item.color}
|
||||
component='a'
|
||||
leftSection={
|
||||
<item.icon
|
||||
style={{ width: rem(16), height: rem(16) }}
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
}
|
||||
href={item.href}
|
||||
>
|
||||
{item.label}
|
||||
</Menu.Item>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ import { TbLogout, TbSettings } from "react-icons/tb"
|
|||
export interface UserMenuItem {
|
||||
label: string,
|
||||
icon: React.FC<any>,
|
||||
color?: ThemeIconProps['color']
|
||||
color?: ThemeIconProps['color'],
|
||||
href?: string,
|
||||
}
|
||||
|
||||
const userMenuItems: UserMenuItem[] = [
|
||||
|
|
@ -16,7 +17,8 @@ const userMenuItems: UserMenuItem[] = [
|
|||
{
|
||||
label: "Logout",
|
||||
icon: TbLogout,
|
||||
color: "red"
|
||||
color: "red",
|
||||
href: "/logout"
|
||||
}
|
||||
];
|
||||
|
||||
|
|
@ -4,19 +4,29 @@ import { cookies } from "next/headers"
|
|||
import "server-only"
|
||||
import { decodeJwtToken } from "../authUtils";
|
||||
import prisma from "@/db";
|
||||
import AuthError, { AuthErrorCode } from "../AuthError";
|
||||
import logout from "./logout";
|
||||
|
||||
export default async function getUser(){
|
||||
const token = cookies().get('token');
|
||||
try {
|
||||
const token = cookies().get('token');
|
||||
|
||||
if (!token) return null;
|
||||
if (!token) return null;
|
||||
|
||||
const decodedToken = decodeJwtToken(token.value) as {id: string, iat: number};
|
||||
const decodedToken = decodeJwtToken(token.value) as {id: string, iat: number};
|
||||
console.log('token', decodedToken)
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: decodedToken.id
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: decodedToken.id
|
||||
}
|
||||
});
|
||||
|
||||
return user;
|
||||
} catch (e: unknown){
|
||||
if (e instanceof AuthError && e.errorCode === AuthErrorCode.INVALID_JWT_TOKEN){
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return user;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
src/features/auth/actions/guestOnly.ts
Normal file
13
src/features/auth/actions/guestOnly.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"use server"
|
||||
|
||||
import { redirect } from "next/navigation";
|
||||
import getUser from "./getUser"
|
||||
|
||||
export default async function guestOnly(){
|
||||
|
||||
const user = await getUser();
|
||||
|
||||
if (user){
|
||||
redirect("dashboard")
|
||||
}
|
||||
}
|
||||
16
src/features/auth/actions/logout.ts
Normal file
16
src/features/auth/actions/logout.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"use server"
|
||||
|
||||
import { cookies } from "next/headers"
|
||||
import { redirect } from "next/navigation";
|
||||
import "server-only"
|
||||
|
||||
/**
|
||||
* Handles user logout by deleting the authentication token and redirecting to the login page.
|
||||
* This function is intended to be used on the server side.
|
||||
*
|
||||
* @returns A promise that resolves when the logout process is complete.
|
||||
*/
|
||||
export default async function logout(){
|
||||
cookies().delete("token");
|
||||
redirect("/login")
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user