diff --git a/dictation_client/src/App.tsx b/dictation_client/src/App.tsx
index f730016..803f215 100644
--- a/dictation_client/src/App.tsx
+++ b/dictation_client/src/App.tsx
@@ -11,6 +11,13 @@ import { selectSnackber } from "features/ui/selectors";
import { closeSnackbar } from "features/ui/uiSlice";
import { UNAUTHORIZED_TO_CONTINUE_ERROR_CODES } from "components/auth/constants";
import { clearUserInfo } from "features/login";
+import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
+
+/*
+UpdateTokenTimerをApp.tsxに移動する(2024年6月27日)
+各画面ごとにトークンの期限チェック~自動更新を行う処理を配置していたが、
+全画面で共通の処理であることと、画面遷移時にチェックのインターバルがリセットされることを考慮し、App.tsxに移動する。
+*/
const App = (): JSX.Element => {
const dispatch = useDispatch();
@@ -82,6 +89,7 @@ const App = (): JSX.Element => {
/>
+
>
);
diff --git a/dictation_client/src/components/auth/updateTokenTimer.tsx b/dictation_client/src/components/auth/updateTokenTimer.tsx
index b615ac6..6441cfc 100644
--- a/dictation_client/src/components/auth/updateTokenTimer.tsx
+++ b/dictation_client/src/components/auth/updateTokenTimer.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback } from "react";
+import React, { useCallback, useLayoutEffect, useState } from "react";
import { AppDispatch } from "app/store";
import { decodeToken } from "common/decodeToken";
import { useInterval } from "common/useInterval";
@@ -17,41 +17,58 @@ import { TOKEN_UPDATE_INTERVAL_MS, TOKEN_UPDATE_TIME } from "./constants";
export const UpdateTokenTimer = () => {
const dispatch: AppDispatch = useDispatch();
const navigate = useNavigate();
+ // トークンの更新中かどうか
+ const [isUpdating, setIsUpdating] = useState(false);
const delegattionToken = useSelector(selectDelegationAccessToken);
// 期限が5分以内であれば更新APIを呼ぶ
const updateToken = useCallback(async () => {
- // localStorageからトークンを取得
- const jwt = loadAccessToken();
- // 現在時刻を取得
- const now = DateTime.local().toSeconds();
- // selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
- if (jwt) {
- const token = decodeToken(jwt);
- if (token) {
- const { exp } = token;
- if (exp - now <= TOKEN_UPDATE_TIME) {
- await dispatch(updateTokenAsync());
- }
- }
+ if (isUpdating) {
+ return;
}
-
- // 代行操作トークン更新処理
- if (delegattionToken) {
- const token = decodeToken(delegattionToken);
- if (token) {
- const { exp } = token;
- if (exp - now <= TOKEN_UPDATE_TIME) {
- const { meta } = await dispatch(updateDelegationTokenAsync());
- if (meta.requestStatus === "rejected") {
- dispatch(cleanupDelegateAccount());
- navigate("/partners");
+ setIsUpdating(true);
+ try {
+ // localStorageからトークンを取得
+ const jwt = loadAccessToken();
+ // 現在時刻を取得
+ const now = DateTime.local().toSeconds();
+ // selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
+ if (jwt) {
+ const token = decodeToken(jwt);
+ if (token) {
+ const { exp } = token;
+ if (exp - now <= TOKEN_UPDATE_TIME) {
+ await dispatch(updateTokenAsync());
}
}
}
+
+ // 代行操作トークン更新処理
+ if (delegattionToken) {
+ const token = decodeToken(delegattionToken);
+ if (token) {
+ const { exp } = token;
+ if (exp - now <= TOKEN_UPDATE_TIME) {
+ const { meta } = await dispatch(updateDelegationTokenAsync());
+ if (meta.requestStatus === "rejected") {
+ dispatch(cleanupDelegateAccount());
+ navigate("/partners");
+ }
+ }
+ }
+ }
+ } catch (e) {
+ // eslint-disable-next-line no-console
+ console.error("Token update error:", e);
+ } finally {
+ setIsUpdating(false);
}
- }, [dispatch, delegattionToken, navigate]);
+ }, [isUpdating, delegattionToken, dispatch, navigate]);
+ useLayoutEffect(() => {
+ updateToken();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
useInterval(updateToken, TOKEN_UPDATE_INTERVAL_MS);
diff --git a/dictation_client/src/pages/AccountPage/index.tsx b/dictation_client/src/pages/AccountPage/index.tsx
index e8a118f..72d8c7f 100644
--- a/dictation_client/src/pages/AccountPage/index.tsx
+++ b/dictation_client/src/pages/AccountPage/index.tsx
@@ -1,5 +1,4 @@
import { AppDispatch } from "app/store";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@@ -106,7 +105,6 @@ const AccountPage: React.FC = (): JSX.Element => {
)}
-
diff --git a/dictation_client/src/pages/LicensePage/licenseOrderHistory.tsx b/dictation_client/src/pages/LicensePage/licenseOrderHistory.tsx
index 1a3a4cb..6c874d1 100644
--- a/dictation_client/src/pages/LicensePage/licenseOrderHistory.tsx
+++ b/dictation_client/src/pages/LicensePage/licenseOrderHistory.tsx
@@ -1,6 +1,5 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { useCallback, useEffect } from "react";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { isApproveTier } from "features/auth";
import { TIERS } from "components/auth/constants";
import Footer from "components/footer";
@@ -166,7 +165,6 @@ export const LicenseOrderHistory: React.FC
= (
delegationAccessToken &&
}
-
diff --git a/dictation_client/src/pages/LicensePage/licenseSummary.tsx b/dictation_client/src/pages/LicensePage/licenseSummary.tsx
index 586dca8..641c8a4 100644
--- a/dictation_client/src/pages/LicensePage/licenseSummary.tsx
+++ b/dictation_client/src/pages/LicensePage/licenseSummary.tsx
@@ -1,5 +1,4 @@
import React, { useCallback, useEffect, useState } from "react";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import styles from "styles/app.module.scss";
@@ -149,8 +148,6 @@ export const LicenseSummary: React.FC
= (
>
{delegationAccessToken && }
-
-
diff --git a/dictation_client/src/pages/LicensePage/partnerLicense.tsx b/dictation_client/src/pages/LicensePage/partnerLicense.tsx
index 03cf8aa..06bd003 100644
--- a/dictation_client/src/pages/LicensePage/partnerLicense.tsx
+++ b/dictation_client/src/pages/LicensePage/partnerLicense.tsx
@@ -2,7 +2,6 @@ import React, { useCallback, useState, useEffect } from "react";
import Footer from "components/footer";
import Header from "components/header";
import styles from "styles/app.module.scss";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "app/store";
import { getTranslationID } from "translation";
@@ -263,7 +262,6 @@ const PartnerLicense: React.FC = (): JSX.Element => {
{!islicenseOrderHistoryOpen && !isViewDetailsOpen && (
-
diff --git a/dictation_client/src/pages/PartnerPage/index.tsx b/dictation_client/src/pages/PartnerPage/index.tsx
index dac23a2..dff2011 100644
--- a/dictation_client/src/pages/PartnerPage/index.tsx
+++ b/dictation_client/src/pages/PartnerPage/index.tsx
@@ -1,6 +1,5 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import { AppDispatch } from "app/store";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@@ -169,7 +168,6 @@ const PartnerPage: React.FC = (): JSX.Element => {
/>
-
diff --git a/dictation_client/src/pages/SupportPage/index.tsx b/dictation_client/src/pages/SupportPage/index.tsx
index ecbb892..b5955d6 100644
--- a/dictation_client/src/pages/SupportPage/index.tsx
+++ b/dictation_client/src/pages/SupportPage/index.tsx
@@ -1,6 +1,5 @@
import React from "react";
import Header from "components/header";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useTranslation } from "react-i18next";
import { getTranslationID } from "translation";
import styles from "styles/app.module.scss";
@@ -12,7 +11,6 @@ const SupportPage: React.FC = () => {
return (
-
diff --git a/dictation_client/src/pages/TemplateFilePage/index.tsx b/dictation_client/src/pages/TemplateFilePage/index.tsx
index f50dd0f..3be393b 100644
--- a/dictation_client/src/pages/TemplateFilePage/index.tsx
+++ b/dictation_client/src/pages/TemplateFilePage/index.tsx
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "app/store";
import Header from "components/header";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useTranslation } from "react-i18next";
import { getTranslationID } from "translation";
import undo from "assets/images/undo.svg";
@@ -69,7 +68,6 @@ export const TemplateFilePage: React.FC = () => {
>
{delegationAccessToken &&
}
-
diff --git a/dictation_client/src/pages/TypistGroupSettingPage/index.tsx b/dictation_client/src/pages/TypistGroupSettingPage/index.tsx
index c4f9e1d..1559c02 100644
--- a/dictation_client/src/pages/TypistGroupSettingPage/index.tsx
+++ b/dictation_client/src/pages/TypistGroupSettingPage/index.tsx
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from "react";
import Header from "components/header";
import Footer from "components/footer";
import styles from "styles/app.module.scss";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import progress_activit from "assets/images/progress_activit.svg";
import undo from "assets/images/undo.svg";
import group_add from "assets/images/group_add.svg";
@@ -93,7 +92,6 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken &&
}
-
diff --git a/dictation_client/src/pages/UserListPage/index.tsx b/dictation_client/src/pages/UserListPage/index.tsx
index c8a2ba4..d97a50f 100644
--- a/dictation_client/src/pages/UserListPage/index.tsx
+++ b/dictation_client/src/pages/UserListPage/index.tsx
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useState } from "react";
import Header from "components/header";
import Footer from "components/footer";
import styles from "styles/app.module.scss";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useDispatch, useSelector } from "react-redux";
import {
listUsersAsync,
@@ -153,7 +152,6 @@ const UserListPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken &&
}
-
diff --git a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx
index 960176d..1b2f728 100644
--- a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx
+++ b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx
@@ -1,4 +1,3 @@
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@@ -138,7 +137,6 @@ const WorktypeIdSettingPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken &&
}
-
diff --git a/dictation_client/src/pages/WorkflowPage/index.tsx b/dictation_client/src/pages/WorkflowPage/index.tsx
index 483b845..12025a7 100644
--- a/dictation_client/src/pages/WorkflowPage/index.tsx
+++ b/dictation_client/src/pages/WorkflowPage/index.tsx
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from "react";
import Header from "components/header";
import Footer from "components/footer";
import styles from "styles/app.module.scss";
-import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import ruleAddImg from "assets/images/rule_add.svg";
import templateSettingImg from "assets/images/template_setting.svg";
import worktypeSettingImg from "assets/images/worktype_setting.svg";
@@ -83,7 +82,6 @@ const WorkflowPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken &&
}
-