🐛 fix(authGuard): remove unnecessary import statement
✨ feat(authContext): add authenticationErrorCount property to AuthContextType to keep track of authentication errors 🐛 fix(authContext): fix typo in getAuthentication function, change 'refresh_token' to 'access_token' 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(authContext): remove unnecessary whitespace 🐛 fix(auth
This commit is contained in:
parent
0ec8d43fd6
commit
2d80efb09d
7 changed files with 62 additions and 40 deletions
|
|
@ -5,7 +5,6 @@ import { AuthContext } from "../../contexts/authContext";
|
||||||
export const ProtectedRoute = ({ children }) => {
|
export const ProtectedRoute = ({ children }) => {
|
||||||
const { isAuthenticated, logout, getAuthentication } =
|
const { isAuthenticated, logout, getAuthentication } =
|
||||||
useContext(AuthContext);
|
useContext(AuthContext);
|
||||||
|
|
||||||
if (!isAuthenticated && !getAuthentication()) {
|
if (!isAuthenticated && !getAuthentication()) {
|
||||||
logout();
|
logout();
|
||||||
return <Navigate to="/login" replace />;
|
return <Navigate to="/login" replace />;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ const initialValue: AuthContextType = {
|
||||||
userData: null,
|
userData: null,
|
||||||
setUserData: () => {},
|
setUserData: () => {},
|
||||||
getAuthentication: () => false,
|
getAuthentication: () => false,
|
||||||
|
authenticationErrorCount: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AuthContext = createContext<AuthContextType>(initialValue);
|
export const AuthContext = createContext<AuthContextType>(initialValue);
|
||||||
|
|
@ -35,7 +36,7 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
|
|
||||||
function getAuthentication(){
|
function getAuthentication(){
|
||||||
const storedRefreshToken = cookies.get('refresh_token');
|
const storedRefreshToken = cookies.get('refresh_token');
|
||||||
const storedAccess = cookies.get('refresh_token');
|
const storedAccess = cookies.get('access_token');
|
||||||
const auth = storedAccess && storedRefreshToken ? true : false;
|
const auth = storedAccess && storedRefreshToken ? true : false;
|
||||||
return auth;
|
return auth;
|
||||||
}
|
}
|
||||||
|
|
@ -49,12 +50,11 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
cookies.remove('access_token');
|
cookies.remove('access_token', { path: '/' });
|
||||||
cookies.remove('refresh_token');
|
cookies.remove('refresh_token', { path: '/' });
|
||||||
setAccessToken(null);
|
setAccessToken(null);
|
||||||
setRefreshToken(null);
|
setRefreshToken(null);
|
||||||
setIsAuthenticated(false);
|
setIsAuthenticated(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refreshAccessToken(refreshToken: string) {
|
async function refreshAccessToken(refreshToken: string) {
|
||||||
|
|
@ -91,7 +91,8 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
refreshAccessToken,
|
refreshAccessToken,
|
||||||
setUserData,
|
setUserData,
|
||||||
userData,
|
userData,
|
||||||
getAuthentication
|
getAuthentication,
|
||||||
|
authenticationErrorCount: 0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { renewAccessToken } from ".";
|
||||||
import { URL_EXCLUDED_FROM_ERROR_RETRIES } from "../../constants/constants";
|
import { URL_EXCLUDED_FROM_ERROR_RETRIES } from "../../constants/constants";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
|
||||||
// Create a new Axios instance
|
// Create a new Axios instance
|
||||||
const api: AxiosInstance = axios.create({
|
const api: AxiosInstance = axios.create({
|
||||||
|
|
@ -13,23 +14,29 @@ const api: AxiosInstance = axios.create({
|
||||||
|
|
||||||
function ApiInterceptor() {
|
function ApiInterceptor() {
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
const { accessToken, login, logout } = useContext(AuthContext);
|
let { accessToken, login, logout, authenticationErrorCount } = useContext(AuthContext);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const cookies = new Cookies();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interceptor = api.interceptors.response.use(
|
const interceptor = api.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
async (error: AxiosError) => {
|
async (error: AxiosError) => {
|
||||||
if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) {
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
if (error.response?.status === 401) {
|
if (error.response?.status === 401) {
|
||||||
const refreshToken = localStorage.getItem("refresh_token");
|
const refreshToken = cookies.get('refresh_token');
|
||||||
|
|
||||||
if (refreshToken) {
|
if (refreshToken) {
|
||||||
|
authenticationErrorCount = authenticationErrorCount + 1;
|
||||||
|
if(authenticationErrorCount > 3){
|
||||||
|
authenticationErrorCount = 0;
|
||||||
|
logout();
|
||||||
|
navigate("/login");
|
||||||
|
}
|
||||||
|
|
||||||
const res = await renewAccessToken(refreshToken);
|
const res = await renewAccessToken(refreshToken);
|
||||||
login(res.data.access_token, res.data.refresh_token);
|
login(res.data.access_token, res.data.refresh_token);
|
||||||
try {
|
try {
|
||||||
const accessToken = localStorage.getItem("access_token");
|
const accessToken = cookies.get('access_token');
|
||||||
delete error.config.headers["Authorization"];
|
delete error.config.headers["Authorization"];
|
||||||
error.config.headers["Authorization"] = `Bearer ${accessToken}`;
|
error.config.headers["Authorization"] = `Bearer ${accessToken}`;
|
||||||
const response = await axios.request(error.config);
|
const response = await axios.request(error.config);
|
||||||
|
|
@ -41,30 +48,40 @@ function ApiInterceptor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else{
|
||||||
let retryCount = 0;
|
logout();
|
||||||
while (retryCount < 4) {
|
navigate("/login");
|
||||||
await sleep(5000); // Sleep for 5 seconds
|
|
||||||
retryCount++;
|
|
||||||
try {
|
|
||||||
const response = await axios.request(error.config);
|
|
||||||
return response;
|
|
||||||
} catch (error) {
|
|
||||||
if (retryCount === 3) {
|
|
||||||
setErrorData({
|
|
||||||
title: "There was an error on web connection, please: ",
|
|
||||||
list: [
|
|
||||||
"Refresh the page",
|
|
||||||
"Use a new flow tab",
|
|
||||||
"Check if the backend is up",
|
|
||||||
"Endpoint: " + error.config?.url,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
// if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) {
|
||||||
|
return Promise.reject(error);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// let retryCount = 0;
|
||||||
|
// while (retryCount < 4) {
|
||||||
|
// await sleep(5000); // Sleep for 5 seconds
|
||||||
|
// retryCount++;
|
||||||
|
// try {
|
||||||
|
// const response = await axios.request(error.config);
|
||||||
|
// return response;
|
||||||
|
// } catch (error) {
|
||||||
|
// if (retryCount === 3) {
|
||||||
|
// setErrorData({
|
||||||
|
// title: "There was an error on web connection, please: ",
|
||||||
|
// list: [
|
||||||
|
// "Refresh the page",
|
||||||
|
// "Use a new flow tab",
|
||||||
|
// "Check if the backend is up",
|
||||||
|
// "Endpoint: " + error.config?.url,
|
||||||
|
// ],
|
||||||
|
// });
|
||||||
|
// return Promise.reject(error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,7 @@ export async function renewAccessToken(token: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUsers(): Promise<Users> {
|
export async function getAllUsers(): Promise<Users> {
|
||||||
try {
|
try {
|
||||||
return await api.get(`${BASE_URL_API}user`);
|
return await api.get(`${BASE_URL_API}user`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,16 @@ export default function UserManagementModal({
|
||||||
index,
|
index,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
}: UserManagementType) {
|
}: UserManagementType) {
|
||||||
|
|
||||||
const Icon: any = nodeIconsLucide[icon];
|
const Icon: any = nodeIconsLucide[icon];
|
||||||
const [pwdVisible, setPwdVisible] = useState(false);
|
const [pwdVisible, setPwdVisible] = useState(false);
|
||||||
const [confirmPwdVisible, setConfirmPwdVisible] = useState(false);
|
const [confirmPwdVisible, setConfirmPwdVisible] = useState(false);
|
||||||
|
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const [password, setPassword] = useState(data?.password ?? "");
|
const [password, setPassword] = useState(data?.password ?? "");
|
||||||
const [username, setUserName] = useState(data?.username ?? "");
|
const [username, setUserName] = useState(data?.username ?? "");
|
||||||
const [confirmPassword, setConfirmPassword] = useState(data?.password ?? "");
|
const [confirmPassword, setConfirmPassword] = useState(data?.password ?? "");
|
||||||
const [isDisabled, setIsDisabled] = useState(data?.is_disabled ?? false);
|
const [isDisabled, setIsDisabled] = useState(data?.is_disabled ?? false);
|
||||||
const [isSuperUser, setIsSuperUser] = useState(data?.is_superuser ?? false);
|
const [isSuperUser, setIsSuperUser] = useState(data?.is_superuser ?? false);
|
||||||
|
|
||||||
const [inputState, setInputState] = useState<UserInputType>(CONTROL_NEW_USER);
|
const [inputState, setInputState] = useState<UserInputType>(CONTROL_NEW_USER);
|
||||||
|
|
||||||
function handleInput({
|
function handleInput({
|
||||||
|
|
@ -47,6 +45,11 @@ export default function UserManagementModal({
|
||||||
if (!data) {
|
if (!data) {
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
handleInput({ target: { name: "username", value: username } });
|
||||||
|
handleInput({ target: { name: "is_disabled", value: isDisabled } });
|
||||||
|
handleInput({ target: { name: "is_superuser", value: isSuperUser } });
|
||||||
|
}
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
|
|
@ -149,7 +152,7 @@ export default function UserManagementModal({
|
||||||
}}
|
}}
|
||||||
value={password}
|
value={password}
|
||||||
className="primary-input"
|
className="primary-input"
|
||||||
required
|
required={data ? false : true}
|
||||||
type={pwdVisible ? "text" : "password"}
|
type={pwdVisible ? "text" : "password"}
|
||||||
/>
|
/>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
|
|
@ -203,7 +206,7 @@ export default function UserManagementModal({
|
||||||
}}
|
}}
|
||||||
value={confirmPassword}
|
value={confirmPassword}
|
||||||
className="primary-input"
|
className="primary-input"
|
||||||
required
|
required={data ? false : true}
|
||||||
type={confirmPwdVisible ? "text" : "password"}
|
type={confirmPwdVisible ? "text" : "password"}
|
||||||
/>
|
/>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export default function AdminPage() {
|
||||||
const [size, setPageSize] = useState(10);
|
const [size, setPageSize] = useState(10);
|
||||||
const [index, setPageIndex] = useState(0);
|
const [index, setPageIndex] = useState(0);
|
||||||
const [loadingUsers, setLoadingUsers] = useState(true);
|
const [loadingUsers, setLoadingUsers] = useState(true);
|
||||||
|
const [totalRowsCount, setTotalRowsCount] = useState(0);
|
||||||
const { setErrorData, setSuccessData } = useContext(alertContext);
|
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||||
|
|
||||||
const userList = useRef([]);
|
const userList = useRef([]);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export type AuthContextType = {
|
||||||
userData: userData | null;
|
userData: userData | null;
|
||||||
setUserData: (userData: userData | null) => void;
|
setUserData: (userData: userData | null) => void;
|
||||||
getAuthentication: () => boolean;
|
getAuthentication: () => boolean;
|
||||||
|
authenticationErrorCount: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type userData = {
|
export type userData = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue