Merged PR 673: ログイン画面へのブラウザバック時のローディング対応

## 概要
[Task3380: ログイン画面へのブラウザバック時のローディング対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3380)

- ログイン済み後にブラウザバックした際にローディング画面からログイン後の画面に遷移する処理を追加しました。
  - loginPage
  - AuthPage
  - TermsPage

## レビューポイント
- 対応ページと対応する箇所は適切でしょうか?
  - 既存のuseEffectの中に処理を追加しています。

## UIの変更
- なし

## 動作確認状況
- ローカルで確認
This commit is contained in:
makabe.t 2024-01-11 08:22:31 +00:00
parent 196a8018e5
commit 6111583678
4 changed files with 129 additions and 32 deletions

View File

@ -10,6 +10,14 @@ import {
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import {
clearToken,
isAdminUser,
isApproveTier,
isStandardUser,
loadAccessToken,
} from "features/auth";
import { TIERS } from "components/auth/constants";
const AuthPage: React.FC = (): JSX.Element => {
const { instance } = useMsal();
@ -26,6 +34,39 @@ const AuthPage: React.FC = (): JSX.Element => {
(async () => {
try {
// ログイン済みの場合、ログイン後の遷移先を決定する
if (loadAccessToken()) {
// 第一~第四階層の管理者はライセンス画面へ遷移
if (
isApproveTier([
TIERS.TIER1,
TIERS.TIER2,
TIERS.TIER3,
TIERS.TIER4,
]) &&
isAdminUser()
) {
navigate("/license");
return;
}
// 第五階層の管理者はユーザー画面へ遷移
if (isApproveTier([TIERS.TIER5]) && isAdminUser()) {
navigate("/user");
return;
}
// 一般ユーザーはdictationPageへ遷移
if (isStandardUser()) {
navigate("/dictations");
return;
}
// それ以外は認証エラー画面へ遷移
instance.logoutRedirect({
postLogoutRedirectUri: "/AuthError",
});
clearToken();
return;
}
const loginResult = await instance.handleRedirectPromise();
// eslint-disable-next-line

View File

@ -122,7 +122,7 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
<dt>{t(getTranslationID("dictationPage.label.transcriptionist"))}</dt>
<dd>{selectedFileTask?.typist?.name ?? ""}</dd>
<dd className={`${styles.full} ${styles.alignRight}`}>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
<a onClick={closePopup} className={`${styles.buttonText}`}>
<img src={close} className={styles.modalTitleIcon} alt="close" />
{t(getTranslationID("filePropertyPopup.label.close"))}

View File

@ -28,6 +28,33 @@ const LoginPage: React.FC = (): JSX.Element => {
selectLocalStorageKeyforIdToken
);
// ログイン後の遷移先を決定する
const navigateToLoginedPage = useCallback(() => {
// 第一~第四階層の管理者はライセンス画面へ遷移
if (
isApproveTier([TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4]) &&
isAdminUser()
) {
navigate("/license");
return;
}
// 第五階層の管理者はユーザー画面へ遷移
if (isApproveTier([TIERS.TIER5]) && isAdminUser()) {
navigate("/user");
return;
}
// 一般ユーザーはdictationPageへ遷移
if (isStandardUser()) {
navigate("/dictations");
return;
}
// それ以外は認証エラー画面へ遷移
instance.logoutRedirect({
postLogoutRedirectUri: "/AuthError",
});
clearToken();
}, [instance, navigate]);
const tokenSet = useCallback(
async (idToken: string) => {
// ログイン処理呼び出し
@ -59,44 +86,36 @@ const LoginPage: React.FC = (): JSX.Element => {
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// 第一~第四階層の管理者はライセンス画面へ遷移
if (
isApproveTier([TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4]) &&
isAdminUser()
) {
navigate("/license");
return;
}
// 第五階層の管理者はユーザー画面へ遷移
if (isApproveTier([TIERS.TIER5]) && isAdminUser()) {
navigate("/user");
return;
}
// 一般ユーザーはdictationPageへ遷移
if (isStandardUser()) {
navigate("/dictations");
return;
}
// それ以外は認証エラー画面へ遷移
instance.logoutRedirect({
postLogoutRedirectUri: "/AuthError",
});
clearToken();
// ログイン成功した場合、適切なページに遷移する
navigateToLoginedPage();
}
},
[dispatch, i18n.language, instance, navigate]
[dispatch, i18n.language, instance, navigate, navigateToLoginedPage]
);
useEffect(() => {
// AADB2Cのログイン画面とLoginPageを経由していない場合はトップページに遷移する
if (!localStorageKeyforIdToken) {
navigate("/");
return;
}
// idTokenStringがあるか⇒認証中
// accessTokenがある場合⇒ログイン済み
// どちらもなければ直打ち
(async () => {
// IDトークンの取得
if (loadAccessToken()) {
navigateToLoginedPage();
return;
}
// AADB2Cのログイン画面とLoginPageを経由していない場合はトップページに遷移する
if (!localStorageKeyforIdToken) {
navigate("/");
return;
}
const idTokenString = localStorage.getItem(localStorageKeyforIdToken);
if (idTokenString === null) {
navigate("/");
return;
}
if (idTokenString) {
const idTokenObject = JSON.parse(idTokenString);
if (isIdToken(idTokenObject)) {

View File

@ -18,10 +18,19 @@ import {
} from "features//terms";
import { selectLocalStorageKeyforIdToken } from "features/login";
import { useNavigate } from "react-router-dom";
import {
clearToken,
isAdminUser,
isApproveTier,
isStandardUser,
loadAccessToken,
} from "features/auth";
import { useMsal } from "@azure/msal-react";
const TermsPage: React.FC = (): JSX.Element => {
const [t] = useTranslation();
const dispatch: AppDispatch = useDispatch();
const { instance } = useMsal();
const navigate = useNavigate();
const updateAccceptVersions = useSelector(selectTermVersions);
const localStorageKeyforIdToken = useSelector(
@ -40,6 +49,34 @@ const TermsPage: React.FC = (): JSX.Element => {
// 画面起動時
useEffect(() => {
// ログイン済みの場合、ログイン後の遷移先を決定する
if (loadAccessToken()) {
// 第一~第四階層の管理者はライセンス画面へ遷移
if (
isApproveTier([TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4]) &&
isAdminUser()
) {
navigate("/license");
return;
}
// 第五階層の管理者はユーザー画面へ遷移
if (isApproveTier([TIERS.TIER5]) && isAdminUser()) {
navigate("/user");
return;
}
// 一般ユーザーはdictationPageへ遷移
if (isStandardUser()) {
navigate("/dictations");
return;
}
// それ以外は認証エラー画面へ遷移
instance.logoutRedirect({
postLogoutRedirectUri: "/AuthError",
});
clearToken();
return;
}
dispatch(getTermsInfoAsync());
if (localStorageKeyforIdToken) {
dispatch(getAccountInfoMinimalAccessAsync({ localStorageKeyforIdToken }));