diff --git a/src/components/Require2FA.js b/src/components/Require2FA.js
new file mode 100644
index 0000000..19f266e
--- /dev/null
+++ b/src/components/Require2FA.js
@@ -0,0 +1,52 @@
+// src/components/Require2FA.jsx
+import React, { useState, useEffect } from 'react';
+import { Navigate } from 'react-router-dom';
+import { Box, CircularProgress, Typography } from '@mui/material';
+import axios from 'axios';
+import { apiPath } from '../auth/utils';
+
+const Require2FA = ({ children }) => {
+ const [is2FAEnabled, setIs2FAEnabled] = useState(null); // null = loading
+ const [error, setError] = useState(false);
+
+ useEffect(() => {
+ const check2FA = async () => {
+ try {
+ const response = await axios.get(`${apiPath}/2fa/status`, {
+ headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` }
+ });
+ setIs2FAEnabled(response.data.enabled);
+ } catch (err) {
+ // Fallback to localStorage (same logic as in Profile page)
+ try {
+ const userData = JSON.parse(localStorage.getItem('userData') || '{}');
+ setIs2FAEnabled(!!userData.twoFactorEnabled);
+ } catch {
+ setError(true);
+ }
+ }
+ };
+
+ check2FA();
+ }, []);
+
+ if (is2FAEnabled === null) {
+ // Still loading
+ return (
+
+
+ Checking security settings...
+
+ );
+ }
+
+ if (!is2FAEnabled || error) {
+ // Redirect to profile page with a clear message
+ return ;
+ }
+
+ // 2FA is enabled → allow access
+ return children;
+};
+
+export default Require2FA;
\ No newline at end of file
diff --git a/src/routes/ClientRoutes.js b/src/routes/ClientRoutes.js
index e8efc48..4c093d0 100644
--- a/src/routes/ClientRoutes.js
+++ b/src/routes/ClientRoutes.js
@@ -1,6 +1,6 @@
import {lazy, useContext} from 'react';
-// project import
+import Require2FA from '../components/Require2FA';
import Loadable from 'components/Loadable';
import MainLayout from "../layout/MainLayout";
import {handleRouteAbility} from "../utils/CommonFunction";
@@ -26,64 +26,78 @@ const ClientRoutes =() => {
path: '/',
element: ,
children: [
+
{
path: 'client',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'CLIENT'),
,
- )
+ )}
+
),
},
{
path: 'client/maintain/:id',
element: (
+
+ {
handleRouteAbility(
ability.can('VIEW', 'CLIENT'),
,
- )
+ )}
+
),
},
{
path: '/pdf/:id',
element: (
- handleRouteAbility(
- ability.can('VIEW', 'CLIENT'),
- ,
-
- )
+
+ {handleRouteAbility(
+ ability.can('VIEW', 'CLIENT'),
+ ,
+
+ )}
+
),
},
{
path: '/pdf/maintain/:id',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'CLIENT'),
,
- )
+ )}
+
),
},
{
path: '/template/',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'TEMPLATE'),
,
- )
+ )}
+
),
},
{
path: '/pdf/form-up-down/:id',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'CLIENT'),
,
- )
+ )}
+
),
},
{
diff --git a/src/routes/SettingRoutes.js b/src/routes/SettingRoutes.js
index c47179b..0314e19 100644
--- a/src/routes/SettingRoutes.js
+++ b/src/routes/SettingRoutes.js
@@ -1,6 +1,6 @@
import {lazy, useContext} from 'react';
-// project import
+import Require2FA from '../components/Require2FA';
import Loadable from 'components/Loadable';
import MainLayout from "../layout/MainLayout";
import AbilityContext from "../components/AbilityProvider";
@@ -102,102 +102,122 @@ const SettingRoutes = () => {
{
path: 'usergroupSearchview',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('MAINTAIN', 'USER_GROUP'),
,
- )
+ )}
+
),
},
{
path: 'userGroup/:id',
element:(
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('MAINTAIN', 'USER_GROUP'),
,
- )
+ )}
+
),
},
{
path: 'user/:id',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'USER'),
,
- )
+ )}
+
),
},
{
path: 'userSearchview',
element:(
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'USER'),
,
- )
+ )}
+
),
},
{
path: 'consultant',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'USER'),
,
- )
+ )}
+
),
},
{
path: 'consultant/:id',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'USER'),
,
- )
+ )}
+
),
},
{
path: 'setting',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('MANAGE', 'SYSTEM_CONFIGURATION'),
,
- )
+ )}
+
),
},
{
path: 'auditLog',
element:(
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'AUDIT_LOG'),
,
- )
+ )}
+
),
},
{
path: 'userActionLog',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'USER'),
,
- )
+ )}
+
),
},
{
path: 'loginLog',
element: (
- handleRouteAbility(
+
+ {handleRouteAbility(
ability.can('VIEW', 'LOGIN_LOG'),
,
- )
+ )}
+
),
},
{