ソースを参照

fixed UI out of sync and multiple token expiry alert

web_access_fix
Jason Chuang 6時間前
コミット
f86a80bfb2
6個のファイルの変更45行の追加8行の削除
  1. +8
    -4
      src/auth/index.js
  2. +4
    -1
      src/layout/MainLayout/Header/index.js
  3. +0
    -2
      src/pages/authentication/auth-forms/AuthLoginCustom.js
  4. +16
    -0
      src/routes/index.js
  5. +15
    -0
      src/store/reducers/authRevision.js
  6. +2
    -1
      src/store/reducers/index.js

+ 8
- 4
src/auth/index.js ファイルの表示

@@ -45,6 +45,8 @@ export const handleLogin = data => {
localStorage.setItem(windowCount, '0')
localStorage.setItem(predictProductionQty, '0')
localStorage.setItem(predictUsageCount, '0')
localStorage.removeItem('expiredAlertShown')
expiredAlertShownInMemory = false
}
}

@@ -100,8 +102,9 @@ export const handleLogoutFunction = () => {
localStorage.removeItem('transactionid')
localStorage.removeItem('searchCriteria')
//localStorage.removeItem(config.storageUserRoleKeyName)
localStorage.removeItem('expiredAlertShown');
expiredAlertShownInMemory = false;
// Do not clear expiredAlertShown / expiredAlertShownInMemory here: logout runs right after
// the token-expired alert, and parallel 401s would each show another popup if we reset.
// Reset those only on successful login (handleLogin).
localStorage.removeItem(refreshIntervalName)
localStorage.removeItem(windowCount)
localStorage.removeItem(predictProductionQty)
@@ -147,7 +150,8 @@ export const SetupAxiosInterceptors = () => {
},
async (error) => {
// const { config, response: { status } } = error
if (error.response.status === 401 && error.config.url !== apiPath + REFRESH_TOKEN) {
const status = error.response?.status
if (status === 401 && error.config?.url !== apiPath + REFRESH_TOKEN) {
// Make a request to refresh the access token
const refreshToken = localStorage.getItem('refreshToken');
if (isRefreshToken) {
@@ -210,7 +214,7 @@ export const SetupAxiosInterceptors = () => {
await window.location.reload();
}

if (error.response.status === 500){
if (error.response?.status === 500){
//setIsUploading(false);
}
// console.log(error)


+ 4
- 1
src/layout/MainLayout/Header/index.js ファイルの表示

@@ -1,6 +1,6 @@
import PropTypes from "prop-types";
import React, { useState, useContext, useEffect, useRef } from "react";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, Link } from "react-router-dom";
import { SysContext } from "components/SysSettingProvider";

@@ -65,6 +65,9 @@ function Header(props) {
const { sysSetting } = useContext(SysContext);
const { window } = props;

/** Subscribe to auth changes (LOGIN/LOGOUT/cross-tab storage); Header reads localStorage and must re-render. */
useSelector((state) => state.authRevision);

const [mobileOpen, setMobileOpen] = useState(false);
const dispatch = useDispatch();
const navigate = useNavigate();


+ 0
- 2
src/pages/authentication/auth-forms/AuthLoginCustom.js ファイルの表示

@@ -42,7 +42,6 @@ import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
import { useDispatch } from "react-redux";
import { handleLogin } from "auth/index";
import useJwt from "auth/jwt/useJwt";
import { handleLogoutFunction } from 'auth/index';
import { FormattedMessage, useIntl } from "react-intl";
import { SysContext } from "components/SysSettingProvider"

@@ -85,7 +84,6 @@ const AuthLoginCustom = () => {
return;
}
loginInFlightRef.current = true;
dispatch(handleLogoutFunction());
setOnLogin(true)
useJwt
.login({ username: values.username, password: values.password })


+ 16
- 0
src/routes/index.js ファイルの表示

@@ -1,3 +1,6 @@
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'

// project import
import LoginRoutes from './LoginRoutes'
// import MainRoutes from './MainRoutes'
@@ -22,6 +25,19 @@ import AfterLoginRoutes from './AfterLoginRoutes';
// ==============================|| ROUTING RENDER ||============================== //

export default function ThemeRoutes() {
const dispatch = useDispatch()
/** Re-run route config when auth changes (same-tab LOGIN/LOGOUT or another tab touching userData). */
useSelector((state) => state.authRevision)

useEffect(() => {
const onStorage = (e) => {
if (e.key === 'userData') {
dispatch({ type: 'AUTH_STORAGE_SYNC' })
}
}
window.addEventListener('storage', onStorage)
return () => window.removeEventListener('storage', onStorage)
}, [dispatch])

if (isUserLoggedIn()) {
//auto logout if token not valid


+ 15
- 0
src/store/reducers/authRevision.js ファイルの表示

@@ -0,0 +1,15 @@
/**
* Bumps when auth-related storage or Redux auth actions change so components
* that read localStorage (e.g. Header) re-render. LOGIN/LOGOUT were previously
* dispatched without any reducer, so the UI could stay stale vs localStorage.
*/
export default function authRevision(state = 0, action) {
switch (action.type) {
case 'LOGIN':
case 'LOGOUT':
case 'AUTH_STORAGE_SYNC':
return state + 1;
default:
return state;
}
}

+ 2
- 1
src/store/reducers/index.js ファイルの表示

@@ -3,9 +3,10 @@ import { combineReducers } from 'redux';

// project import
import menu from './menu';
import authRevision from './authRevision';

// ==============================|| COMBINE REDUCERS ||============================== //

const reducers = combineReducers({ menu });
const reducers = combineReducers({ menu, authRevision });

export default reducers;

読み込み中…
キャンセル
保存