Skip to content

Commit

Permalink
Security issue is solved #32
Browse files Browse the repository at this point in the history
  • Loading branch information
Meefish committed Nov 11, 2024
1 parent 32919f8 commit d9b76ce
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 47 deletions.
57 changes: 31 additions & 26 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,46 @@ import Experiment from './pages/Experiment';
import MessageCreation from './pages/MessageCreation';
import MessageDashboard from './pages/MessageDashboard';
import Unauthorized from './pages/Unauthorized';
import { isAuthenticated } from './services/authService';
import AuthWrapper from './components/AuthWrapper';

const App: React.FC = () => {
return (
<Router>
<AuthWrapper>
<Routes>
{/* Default Route - Redirects to dashboard or login */}
<Route
path="/"
element={<Navigate to={isAuthenticated() ? "/dashboard" : "/login"} replace />}
/>
<Routes>
{/* Public Routes */}
<Route path="/login" element={<Login />} />

{/* Public Route - Login */}
<Route path="/login" element={<Login />} />
{/* Unauthorized Route */}
<Route path="/unauthorized" element={<Unauthorized />} />

{/* Private Routes */}
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/activity" element={<Activity />} />
<Route path="/profile" element={<Profile />} />
<Route path="/export" element={<Export />} />
<Route path="/experimentcreation" element={<ExperimentCreation />} />
<Route path="/experiment/:id" element={<Experiment />} />
<Route path="/messagecreation/:id" element={<MessageCreation />} />
<Route path="/messagedashboard/:id" element={<MessageDashboard />} />
{/* Unauthorized Route */}
<Route path="/unauthorized" element={<Unauthorized />} />
{/* Protected Routes */}
<Route
path="/*"
element={
<AuthWrapper>
<Routes>
{/* Default Route - Redirects to dashboard */}
<Route path="/" element={<Navigate to="/dashboard" replace />} />

{/* Wildcard Route */}
<Route path="*" element={<Navigate to={isAuthenticated() ? "/dashboard" : "/login"} replace />} />
</Routes>
</AuthWrapper>
{/* Private Routes */}
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/activity" element={<Activity />} />
<Route path="/profile" element={<Profile />} />
<Route path="/export" element={<Export />} />
<Route path="/experimentcreation" element={<ExperimentCreation />} />
<Route path="/experiment/:id" element={<Experiment />} />
<Route path="/messagecreation/:id" element={<MessageCreation />} />
<Route path="/messagedashboard/:id" element={<MessageDashboard />} />

{/* Wildcard Route */}
<Route path="*" element={<Navigate to="/dashboard" replace />} />
</Routes>
</AuthWrapper>
}
/>
</Routes>
</Router>
);
};

export default App;
export default App;
38 changes: 23 additions & 15 deletions src/components/AuthWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { isAuthenticated } from '../services/authService';
// components/AuthWrapper.tsx

import React, { useEffect, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { isAuthenticated, getUserRole } from '../services/authService';

interface AuthWrapperProps {
children: React.ReactNode;
}

const AuthWrapper: React.FC<AuthWrapperProps> = ({ children }) => {
const navigate = useNavigate();
const location = useLocation();
const [loading, setLoading] = useState<boolean>(true);

useEffect(() => {
const checkAuthStatus = () => {
const checkAuthStatus = async () => {
if (isAuthenticated()) {
if (window.location.pathname === '/login') {
navigate('/dashboard', { replace: true });
const role = await getUserRole();
if (role === 3) {
// User has the Researcher role
setLoading(false); // Allow rendering of protected components
} else {
// User does not have the Researcher role
navigate('/unauthorized', { replace: true });
}
} else {
if (window.location.pathname !== '/login') {
navigate('/login', { replace: true });
}
// User is not authenticated
navigate('/login', { replace: true });
}
};

checkAuthStatus();
}, [navigate, location]);

// Set an interval to keep checking if the user is authenticated
const intervalId = setInterval(checkAuthStatus, 5000); // Check every 5 seconds

return () => clearInterval(intervalId);
}, [navigate]);
if (loading) {
// You can show a loading indicator while checking authentication
return <div>Loading...</div>;
}

return <>{children}</>;
};

export default AuthWrapper;
export default AuthWrapper;
2 changes: 1 addition & 1 deletion src/pages/MessageCreation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState} from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import Navbar from '../components/Navbar';
import '../styles/MessageCreation.css';
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Unauthorized.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const Unauthorized: React.FC = () => {
It seems like you don't have the <strong>Researcher</strong> role right now.
</p>
<p>
If you believe this is a mistake or you should have the necessary role, please contact
<a href="mailto:[email protected]" > [email protected]</a> for further assistance.
If you believe this is a mistake or you should have the necessary role,
please contact the organization
</p>
</div>
);
Expand Down
20 changes: 20 additions & 0 deletions src/services/authService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { getMyProfile } from './profileService';

const API_URL = 'https://wildlifenl-uu-michi011.apps.cl01.cp.its.uu.nl/auth/';


Expand Down Expand Up @@ -51,3 +53,21 @@ export const isAuthenticated = (): boolean => {
const token = localStorage.getItem('authToken');
return !!token;
};

export const getUserRole = async (): Promise<number | null> => {
try {
const profile = await getMyProfile();

// Check if the user has the Researcher role (ID = 3)
if (
profile.roles &&
profile.roles.some((role) => role.ID === 3)
) {
return 3; // Researcher role ID
}
return null; // User does not have the Researcher role
} catch (error) {
console.error('Error fetching user role:', error);
return null;
}
};
2 changes: 1 addition & 1 deletion src/services/profileService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { User } from '../types/user';
const API_URL = 'https://wildlifenl-uu-michi011.apps.cl01.cp.its.uu.nl/profile/me';
const API_URL = 'https://wildlifenl-uu-michi011.apps.cl01.cp.its.uu.nl/profile/me/';


const getAuthToken = (): string | null => {
Expand Down
1 change: 0 additions & 1 deletion src/styles/MessageCreation.css
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
}

.message-creation-slider-input input[type='range'] {
-webkit-appearance: none;
width: 100%;
height: 5px;
background: #d3d3d3;
Expand Down
1 change: 0 additions & 1 deletion src/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export interface Role {
}

export interface User {
$schema: string;
ID: string;
name: string;
email: string;
Expand Down

0 comments on commit d9b76ce

Please sign in to comment.