import React, { useCallback } from "react"; import { AppDispatch } from "app/store"; import { decodeToken } from "common/decodeToken"; import { useInterval } from "common/useInterval"; import { updateTokenAsync, loadAccessToken, updateDelegationTokenAsync, } from "features/auth"; import { DateTime } from "luxon"; import { useDispatch, useSelector } from "react-redux"; import { selectDelegationAccessToken } from "features/auth/selectors"; import { useNavigate } from "react-router-dom"; import { cleanupDelegateAccount } from "features/partner"; import { TOKEN_UPDATE_INTERVAL_MS, TOKEN_UPDATE_TIME } from "./constants"; export const UpdateTokenTimer = () => { const dispatch: AppDispatch = useDispatch(); const navigate = useNavigate(); 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 (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"); } } } } }, [dispatch, delegattionToken, navigate]); useInterval(updateToken, TOKEN_UPDATE_INTERVAL_MS); // eslint-disable-next-line react/jsx-no-useless-fragment return <>; };