From c87581c9e2c5021540626454075fe707a132fa6e Mon Sep 17 00:00:00 2001 From: Vladislav Date: Mon, 16 Jun 2025 12:34:32 +0500 Subject: [PATCH] feat(client): add auth logic --- client/src/App.tsx | 13 +++++++- client/src/api/api.ts | 49 ++++++++++++++++++++++------- client/src/pages/AccountsPage.tsx | 6 ++++ client/src/pages/LoginPage.tsx | 2 +- client/src/pages/MainLayout.tsx | 19 ----------- client/src/pages/ProtectedRoute.tsx | 15 +++++++-- 6 files changed, 70 insertions(+), 34 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index 3d98dae..97e095a 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,10 +1,21 @@ -import React from 'react'; +/* eslint-disable react-hooks/exhaustive-deps */ +import React, { useEffect } from 'react'; import { Route, Routes } from 'react-router-dom'; import MainLayout from './pages/MainLayout'; import ProtectedRoute from './pages/ProtectedRoute'; import LoginPage from './pages/LoginPage'; +import { useSetUserSelector } from './store/userStore'; function App() { + const setUser = useSetUserSelector(); + + useEffect(() => { + const storedUser = localStorage.getItem('user'); + if (storedUser) { + setUser(JSON.parse(storedUser)); + } + }, []); + return (
diff --git a/client/src/api/api.ts b/client/src/api/api.ts index c691e11..0409bf0 100644 --- a/client/src/api/api.ts +++ b/client/src/api/api.ts @@ -1,8 +1,9 @@ import axios from 'axios'; import { Access, Auth } from '../types/auth'; import { User } from '../types/user'; -import { AuthService } from '../services/auth'; +import { AuthService } from '../services/authService'; import axiosRetry from 'axios-retry'; +import { useAuthStore } from '../store/authStore'; const baseURL = `${process.env.REACT_APP_HTTP_PROTOCOL}://${process.env.REACT_APP_API_URL}/api/v1`; @@ -15,7 +16,10 @@ const base = axios.create({ }); base.interceptors.request.use((config) => { - const token = localStorage.getItem('accessToken'); + if (config.url === '/auth/refresh') { + return config; + } + const token = useAuthStore.getState().accessToken; if (token) { config.headers.Authorization = `Bearer ${token}`; } @@ -43,7 +47,6 @@ base.interceptors.response.use( async function (error) { console.log('error', error); const originalRequest = error.response.config; - console.log('originalRequest._retry', originalRequest); const urlTokens = error?.request?.responseURL.split('/'); const url = urlTokens[urlTokens.length - 1]; console.log('url', url); @@ -55,26 +58,43 @@ base.interceptors.response.use( url !== 'logout' ) { originalRequest._retry = true; - const res = await AuthService.refresh().catch(async () => { + try { + await AuthService.refresh(); + return base(originalRequest); + } catch (error) { await AuthService.logout(); - }); - console.log('res', res); - return await base(originalRequest); + return new Promise(() => {}); + } } return await Promise.reject(error); } ); +interface newAccess { + accessToken: string; + refreshToken: string; +} + const api = { // auth - async login(auth: Auth): Promise { - console.log(auth); - const response = await base.post('/auth', auth); + // async login(auth: Auth): Promise { + async login(auth: Auth): Promise { + // const response = (await base.post) ('/auth', auth); + const response = await base.post('/auth', auth); return response.data; }, async refreshToken(): Promise { - const response = await base.post('/auth/refresh'); + const token = localStorage.getItem('refreshToken'); + const response = await base.post( + '/auth/refresh', + {}, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); return response.data; }, @@ -83,6 +103,13 @@ const api = { const response = await base.get('/profile'); return response.data; }, + + async getUsers(page: number, limit: number): Promise { + const response = await base.get( + `/account?page=${page}&limit=${limit}` + ); + return response.data; + }, }; export default api; diff --git a/client/src/pages/AccountsPage.tsx b/client/src/pages/AccountsPage.tsx index 4387052..e66b21d 100644 --- a/client/src/pages/AccountsPage.tsx +++ b/client/src/pages/AccountsPage.tsx @@ -3,6 +3,10 @@ import { useState } from 'react'; import ContentDrawer from '../components/ContentDrawer'; import UserCreate from '../components/UserCreate'; import { useTranslation } from 'react-i18next'; +import { Button } from 'antd'; +import { UserService } from '../services/userService'; +import { User } from '../types/user'; +import { AuthService } from '../services/authService'; export default function AccountsPage() { const { t } = useTranslation(); @@ -11,6 +15,8 @@ export default function AccountsPage() { const showDrawer = () => setOpen(true); const closeDrawer = () => setOpen(false); + const [accounts, setAccounts] = useState([]); + return ( <>
('15%'); const [collapsedWidth, setCollapsedWidth] = useState(50); - const setUser = useSetUserSelector(); - const calculateWidths = () => { const windowWidth = window.innerWidth; const expanded = Math.min(Math.max(windowWidth * 0.15, 180), 240); @@ -58,21 +54,6 @@ export default function MainLayout() { navigate(key); } - useEffect(() => { - const token = localStorage.getItem('accessToken'); - if (!token) { - navigate('/login'); - } else { - if (localStorage.getItem('user')) { - setUser(JSON.parse(localStorage.getItem('user') as string)); - } else { - UserService.getProfile().then((user) => { - setUser(user); - }); - } - } - }, []); - return ( { + const navigate = useNavigate(); + const user = useUserSelector(); + + useEffect(() => { + if (!user?.id) { + navigate('/login'); + } + }, [user]); + return ; }; export default ProtectedRoute;