diff --git a/RestroHub-FrontEnd/src/components/admin/Header.jsx b/RestroHub-FrontEnd/src/components/admin/Header.jsx index 1a845635..6b3e6727 100644 --- a/RestroHub-FrontEnd/src/components/admin/Header.jsx +++ b/RestroHub-FrontEnd/src/components/admin/Header.jsx @@ -18,6 +18,7 @@ import { useAdminTheme } from '@context/AdminThemeContext'; import profileService from '../../services/user/profileService'; import useWebSocketNotifications from '@hooks/useWebSocketNotifications'; import api from '../../services/common/api'; +import { clearAuthSession } from '../../services/common/authStorage'; const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { const [searchOpen, setSearchOpen] = useState(false); @@ -41,9 +42,7 @@ const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { } catch (error) { console.error('Logout API failed:', error); //catches errors if API call breaks } finally { - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('roles'); + clearAuthSession(); if (api?.defaults?.headers?.common?.Authorization) { //cleans up axios default auth header if it exists delete api.defaults.headers.common.Authorization; @@ -398,4 +397,4 @@ const Header = ({ onMobileMenuClick, collapsed, onCollapseToggle }) => { ); }; -export default Header; \ No newline at end of file +export default Header; diff --git a/RestroHub-FrontEnd/src/hooks/useWebSocketNotifications.js b/RestroHub-FrontEnd/src/hooks/useWebSocketNotifications.js index d5f6076f..24388c9b 100644 --- a/RestroHub-FrontEnd/src/hooks/useWebSocketNotifications.js +++ b/RestroHub-FrontEnd/src/hooks/useWebSocketNotifications.js @@ -2,6 +2,7 @@ import { useState, useEffect, useRef, useCallback } from 'react'; import { Client } from '@stomp/stompjs'; import SockJS from 'sockjs-client/dist/sockjs'; import toast from 'react-hot-toast'; +import { getAccessToken } from '@services/common/authStorage'; // ============================================ // useWebSocketNotifications Hook @@ -55,7 +56,7 @@ const useWebSocketNotifications = (branchId) => { const fetchExisting = async () => { try { - const token = localStorage.getItem('accessToken'); + const token = getAccessToken(); const res = await fetch( `${API_BASE_URL}/secure/api/v1/service-requests/branch/${branchId}`, { headers: { Authorization: `Bearer ${token}` } } @@ -127,7 +128,7 @@ const useWebSocketNotifications = (branchId) => { // Acknowledge a request const acknowledgeRequest = useCallback(async (requestId) => { try { - const token = localStorage.getItem('accessToken'); + const token = getAccessToken(); await fetch( `${API_BASE_URL}/secure/api/v1/service-requests/${requestId}/acknowledge`, { method: 'PATCH', headers: { Authorization: `Bearer ${token}` } } @@ -145,7 +146,7 @@ const useWebSocketNotifications = (branchId) => { // Complete/dismiss a request const completeRequest = useCallback(async (requestId) => { try { - const token = localStorage.getItem('accessToken'); + const token = getAccessToken(); await fetch( `${API_BASE_URL}/secure/api/v1/service-requests/${requestId}/complete`, { method: 'PATCH', headers: { Authorization: `Bearer ${token}` } } diff --git a/RestroHub-FrontEnd/src/pages/public/Login.jsx b/RestroHub-FrontEnd/src/pages/public/Login.jsx index edf9e2ec..248d6a78 100644 --- a/RestroHub-FrontEnd/src/pages/public/Login.jsx +++ b/RestroHub-FrontEnd/src/pages/public/Login.jsx @@ -4,11 +4,11 @@ import { useState } from "react"; import { Link, useNavigate } from "react-router-dom"; import { useFormik } from "formik"; import * as Yup from "yup"; -import axios from "axios"; import toast from "react-hot-toast"; import { GoogleLogin } from "@react-oauth/google"; import { ArrowLeft } from "lucide-react"; import api from "@services/common/api"; +import { storeAuthSession } from "@services/common/authStorage"; import { useTheme } from "@context/ThemeContext"; const API_BASE_URL = @@ -159,7 +159,7 @@ const Login = () => { const [isLoading, setIsLoading] = useState(false); const formik = useFormik({ - initialValues: { username: "", password: "" }, + initialValues: { username: "", password: "", rememberMe: true }, validationSchema, onSubmit: async (values) => { setIsLoading(true); @@ -172,11 +172,12 @@ const Login = () => { if (result.success) { const { accessToken, refreshToken, roles } = result.data; - localStorage.setItem("accessToken", accessToken); - localStorage.setItem("refreshToken", refreshToken); - localStorage.setItem("roles", JSON.stringify(roles)); + storeAuthSession( + { accessToken, refreshToken, roles }, + values.rememberMe + ); - axios.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`; + api.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`; toast.success("Login successful!"); @@ -207,11 +208,12 @@ const handleGoogleLogin = async (credentialResponse) => { if (result.success) { const { accessToken, refreshToken, roles } = result.data; - localStorage.setItem("accessToken", accessToken); - localStorage.setItem("refreshToken", refreshToken); - localStorage.setItem("roles", JSON.stringify(roles)); + storeAuthSession( + { accessToken, refreshToken, roles }, + formik.values.rememberMe + ); - axios.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`; + api.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`; toast.success("Google login successful!"); @@ -374,8 +376,19 @@ const handleGoogleLogin = async (credentialResponse) => { )} - {/* Forgot password */} -