From e729508a14a7f76d26981b931624de552e2433ae Mon Sep 17 00:00:00 2001 From: kayra1 Date: Mon, 22 Jul 2024 11:33:01 +0300 Subject: [PATCH] custom auth hook --- ui/src/app/auth/authContext.tsx | 39 +++++++++++++++++++++++++++++++++ ui/src/app/globals.scss | 6 ----- ui/src/app/layout.tsx | 10 +++++---- ui/src/app/login.tsx | 35 +++++++++++++++-------------- ui/src/app/login/page.tsx | 3 +++ ui/src/app/nav.tsx | 10 ++++----- ui/src/app/types.ts | 7 ++++++ 7 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 ui/src/app/auth/authContext.tsx diff --git a/ui/src/app/auth/authContext.tsx b/ui/src/app/auth/authContext.tsx new file mode 100644 index 0000000..e75b405 --- /dev/null +++ b/ui/src/app/auth/authContext.tsx @@ -0,0 +1,39 @@ +"use client" + +import { createContext, useContext, useState, useEffect } from 'react'; +import { Dispatch, SetStateAction } from 'react'; +import { User } from '../types'; +import { useCookies } from 'react-cookie'; +import { jwtDecode } from 'jwt-decode'; +import { useRouter } from 'next/navigation'; + +type AuthContextType = { + user: User | null + setUser: Dispatch> +} + +const AuthContext = createContext({ user: null, setUser: () => { } }); + +export const AuthProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { + const [cookies, setCookie, removeCookie] = useCookies(['user_token']); + const [user, setUser] = useState(null); + const router = useRouter(); + + useEffect(() => { + const token = cookies.user_token; + if (token) { + let userObject = jwtDecode(cookies.user_token) as User + setUser(userObject); + } else { + router.push('/login'); + } + }, [cookies.user_token, router]); + + return ( + + {children} + + ); +}; + +export const useAuth = () => useContext(AuthContext); \ No newline at end of file diff --git a/ui/src/app/globals.scss b/ui/src/app/globals.scss index aa01402..27827e8 100644 --- a/ui/src/app/globals.scss +++ b/ui/src/app/globals.scss @@ -58,9 +58,3 @@ .certificate-info p { margin: 4px 0; } - -.sidenav-bottom-ul { - bottom: $spv--x-large; - position: absolute; - width: 15rem; -} \ No newline at end of file diff --git a/ui/src/app/layout.tsx b/ui/src/app/layout.tsx index dae56ac..7ed023f 100644 --- a/ui/src/app/layout.tsx +++ b/ui/src/app/layout.tsx @@ -1,7 +1,7 @@ import type { Metadata } from "next"; import './globals.scss' import Navigation from "@/app/nav"; - +import { AuthProvider } from "./auth/authContext"; export const metadata: Metadata = { title: "GoCert", @@ -19,9 +19,11 @@ export default function RootLayout({ - - {children} - + + + {children} + + ); diff --git a/ui/src/app/login.tsx b/ui/src/app/login.tsx index 99e8965..62fecfe 100644 --- a/ui/src/app/login.tsx +++ b/ui/src/app/login.tsx @@ -1,24 +1,25 @@ -import { jwtDecode } from "jwt-decode"; -import { useState } from "react"; -import { useCookies } from "react-cookie" +import { useAuth } from "./auth/authContext"; -type UserObject = { - exp: number - id: number - permissions: number - username: string -} - -export function Login() { - const [cookies, setCookie, removeCookie] = useCookies(['user_token']); - var userObject: UserObject | null = null - if (cookies.user_token) { - userObject = jwtDecode(cookies.user_token) - } +export function AccountTab() { + const authDetails = useAuth() return ( <> { - cookies.user_token ?

{userObject?.username}

: Login + authDetails.user ? +
+ + + {authDetails.user.username} + + +
+ : + + + + Login + + } ) } \ No newline at end of file diff --git a/ui/src/app/login/page.tsx b/ui/src/app/login/page.tsx index 26d8e6e..7ee9a47 100644 --- a/ui/src/app/login/page.tsx +++ b/ui/src/app/login/page.tsx @@ -4,8 +4,10 @@ import { useMutation } from "react-query" import { login } from "../queries" import { useState, ChangeEvent } from "react" import { useCookies } from "react-cookie" +import { useRouter } from "next/navigation" export default function LoginPage() { + const router = useRouter() const [cookies, setCookie, removeCookie] = useCookies(['user_token']); const mutation = useMutation(login, { onSuccess: (e) => { @@ -15,6 +17,7 @@ export default function LoginPage() { secure: true, expires: new Date(new Date().getTime() + 60 * 60 * 1000), }) + router.push('/certificate_requests') }, onError: (e: Error) => { setErrorText(e.message) diff --git a/ui/src/app/nav.tsx b/ui/src/app/nav.tsx index e135e7b..d01d781 100644 --- a/ui/src/app/nav.tsx +++ b/ui/src/app/nav.tsx @@ -4,7 +4,7 @@ import { SetStateAction, Dispatch, useState, useEffect } from "react" import { QueryClient, QueryClientProvider } from "react-query"; import Image from "next/image"; import { Aside, AsideContext } from "./aside"; -import { Login } from "./login" +import { AccountTab } from "./login" export function SideBar({ sidebarVisible, setSidebarVisible }: { sidebarVisible: boolean, setSidebarVisible: Dispatch> }) { const [activeTab, setActiveTab] = useState(""); @@ -27,7 +27,7 @@ export function SideBar({ sidebarVisible, setSidebarVisible }: { sidebarVisible:
diff --git a/ui/src/app/types.ts b/ui/src/app/types.ts index 92d511f..b1f9d2f 100644 --- a/ui/src/app/types.ts +++ b/ui/src/app/types.ts @@ -2,4 +2,11 @@ export type CSREntry = { id: number, csr: string, certificate: string +} + +export type User = { + exp: number + id: number + permissions: number + username: string } \ No newline at end of file