Merge branch 'develop' into ccb
This commit is contained in:
commit
cd277f3f9a
@ -1,8 +1,6 @@
|
|||||||
import AppRouter from "AppRouter";
|
import AppRouter from "AppRouter";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import { PublicClientApplication } from "@azure/msal-browser";
|
import { useMsal } from "@azure/msal-react";
|
||||||
import { MsalProvider, useMsal } from "@azure/msal-react";
|
|
||||||
import { msalConfig } from "common/msalConfig";
|
|
||||||
import { useEffect, useLayoutEffect } from "react";
|
import { useEffect, useLayoutEffect } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import globalAxios, { AxiosError, AxiosResponse } from "axios";
|
import globalAxios, { AxiosError, AxiosResponse } from "axios";
|
||||||
@ -19,7 +17,6 @@ const App = (): JSX.Element => {
|
|||||||
const { instance } = useMsal();
|
const { instance } = useMsal();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const [t, i18n] = useTranslation();
|
const [t, i18n] = useTranslation();
|
||||||
const pca = new PublicClientApplication(msalConfig);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = globalAxios.interceptors.response.use(
|
const id = globalAxios.interceptors.response.use(
|
||||||
(response: AxiosResponse) => response,
|
(response: AxiosResponse) => response,
|
||||||
@ -70,11 +67,9 @@ const App = (): JSX.Element => {
|
|||||||
dispatch(closeSnackbar());
|
dispatch(closeSnackbar());
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<MsalProvider instance={pca}>
|
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppRouter />
|
<AppRouter />
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</MsalProvider>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,3 +76,16 @@ export const getIdTokenFromLocalStorage = (
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// JWTが有効期限切れかどうかを判定する
|
||||||
|
export const isTokenExpired = (token: string | null): boolean => {
|
||||||
|
if (token == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const tokenObject = JSON.parse(atob(token.split(".")[1]));
|
||||||
|
if (isToken(tokenObject)) {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
return tokenObject.exp < now;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|||||||
@ -3,18 +3,25 @@ import React from "react";
|
|||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { I18nextProvider } from "react-i18next";
|
import { I18nextProvider } from "react-i18next";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
import { PublicClientApplication } from "@azure/msal-browser";
|
||||||
|
import { msalConfig } from "common/msalConfig";
|
||||||
|
import { MsalProvider } from "@azure/msal-react";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
import i18n from "./i18n";
|
import i18n from "./i18n";
|
||||||
|
|
||||||
|
const pca = new PublicClientApplication(msalConfig);
|
||||||
|
|
||||||
const container = document.getElementById("root");
|
const container = document.getElementById("root");
|
||||||
if (container) {
|
if (container) {
|
||||||
const root = createRoot(container);
|
const root = createRoot(container);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
<MsalProvider instance={pca}>
|
||||||
<I18nextProvider i18n={i18n} />
|
<I18nextProvider i18n={i18n} />
|
||||||
<App />
|
<App />
|
||||||
|
</MsalProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,14 +10,6 @@ import {
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useNavigate } from "react-router-dom";
|
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 AuthPage: React.FC = (): JSX.Element => {
|
||||||
const { instance } = useMsal();
|
const { instance } = useMsal();
|
||||||
@ -34,38 +26,7 @@ const AuthPage: React.FC = (): JSX.Element => {
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// ログイン済みの場合、ログイン後の遷移先を決定する
|
// idTokenが有効セットされているかを確認する
|
||||||
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();
|
const loginResult = await instance.handleRedirectPromise();
|
||||||
if (loginResult && loginResult.account) {
|
if (loginResult && loginResult.account) {
|
||||||
const { homeAccountId, idTokenClaims } = loginResult.account;
|
const { homeAccountId, idTokenClaims } = loginResult.account;
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export const AuthErrorPage = (): JSX.Element => (
|
export const AuthErrorPage = (): JSX.Element => (
|
||||||
<div>
|
<div>
|
||||||
<p>ログインに失敗しました</p>
|
<p>login failed</p>
|
||||||
<br />
|
<br />
|
||||||
|
<Link to="/">return to TopPage</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useMsal } from "@azure/msal-react";
|
import { useMsal } from "@azure/msal-react";
|
||||||
import { AppDispatch } from "app/store";
|
import { AppDispatch } from "app/store";
|
||||||
import { isIdToken } from "common/token";
|
import { isIdToken, isTokenExpired } from "common/token";
|
||||||
import {
|
import {
|
||||||
clearToken,
|
clearToken,
|
||||||
isAdminUser,
|
isAdminUser,
|
||||||
@ -52,10 +52,10 @@ const LoginPage: React.FC = (): JSX.Element => {
|
|||||||
instance.logoutRedirect({
|
instance.logoutRedirect({
|
||||||
postLogoutRedirectUri: "/AuthError",
|
postLogoutRedirectUri: "/AuthError",
|
||||||
});
|
});
|
||||||
clearToken();
|
dispatch(clearToken());
|
||||||
}, [instance, navigate]);
|
}, [instance, navigate, dispatch]);
|
||||||
|
|
||||||
const tokenSet = useCallback(
|
const tokenSetAndNavigate = useCallback(
|
||||||
async (idToken: string) => {
|
async (idToken: string) => {
|
||||||
// ログイン処理呼び出し
|
// ログイン処理呼び出し
|
||||||
const { meta, payload } = await dispatch(loginAsync({ idToken }));
|
const { meta, payload } = await dispatch(loginAsync({ idToken }));
|
||||||
@ -96,31 +96,32 @@ const LoginPage: React.FC = (): JSX.Element => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// idTokenStringがあるか⇒認証中
|
// idTokenStringがあるか⇒認証中
|
||||||
// accessTokenがある場合⇒ログイン済み
|
// accessTokenがある場合⇒ログイン済みなのにブラウザバックでログイン画面に戻ってきた場合
|
||||||
// どちらもなければ直打ち
|
// どちらもなければURL直打ち
|
||||||
(async () => {
|
(async () => {
|
||||||
if (loadAccessToken()) {
|
// ローカルストレージにidTokenがある場合は取得する
|
||||||
navigateToLoginedPage();
|
let idTokenString: string | null = null;
|
||||||
return;
|
if (localStorageKeyforIdToken !== null) {
|
||||||
|
idTokenString = localStorage.getItem(localStorageKeyforIdToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AADB2Cのログイン画面とLoginPageを経由していない場合はトップページに遷移する
|
// idTokenがない(=正常なログインプロセス中でない)場合は有効なアクセストークンを所持しているか確認し、
|
||||||
if (!localStorageKeyforIdToken) {
|
// 有効であればログイン画面に遷移 or 無効であればトップページに遷移
|
||||||
navigate("/");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const idTokenString = localStorage.getItem(localStorageKeyforIdToken);
|
|
||||||
|
|
||||||
if (idTokenString === null) {
|
if (idTokenString === null) {
|
||||||
|
const token = loadAccessToken();
|
||||||
|
// アクセストークンがない or 有効期限切れ場合はトップページに遷移
|
||||||
|
if (isTokenExpired(token)) {
|
||||||
navigate("/");
|
navigate("/");
|
||||||
|
} else {
|
||||||
|
// 有効なアクセストークンがある場合はログイン画面に遷移
|
||||||
|
navigateToLoginedPage();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idTokenString) {
|
|
||||||
const idTokenObject = JSON.parse(idTokenString);
|
const idTokenObject = JSON.parse(idTokenString);
|
||||||
if (isIdToken(idTokenObject)) {
|
if (isIdToken(idTokenObject)) {
|
||||||
await tokenSet(idTokenObject.secret);
|
await tokenSetAndNavigate(idTokenObject.secret);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
// 画面描画後のみ実行するため引数を設定しない
|
// 画面描画後のみ実行するため引数を設定しない
|
||||||
|
|||||||
@ -40,9 +40,6 @@ export class User {
|
|||||||
@Column({ default: true })
|
@Column({ default: true })
|
||||||
auto_renew: boolean;
|
auto_renew: boolean;
|
||||||
|
|
||||||
@Column({ default: true })
|
|
||||||
license_alert: boolean;
|
|
||||||
|
|
||||||
@Column({ default: true })
|
@Column({ default: true })
|
||||||
notification: boolean;
|
notification: boolean;
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,6 @@ export const makeTestUser = async (
|
|||||||
accepted_dpa_version: d?.accepted_dpa_version ?? "1.0",
|
accepted_dpa_version: d?.accepted_dpa_version ?? "1.0",
|
||||||
email_verified: d?.email_verified ?? true,
|
email_verified: d?.email_verified ?? true,
|
||||||
auto_renew: d?.auto_renew ?? true,
|
auto_renew: d?.auto_renew ?? true,
|
||||||
license_alert: d?.license_alert ?? true,
|
|
||||||
notification: d?.notification ?? true,
|
notification: d?.notification ?? true,
|
||||||
encryption: d?.encryption ?? true,
|
encryption: d?.encryption ?? true,
|
||||||
encryption_password: d?.encryption_password,
|
encryption_password: d?.encryption_password,
|
||||||
@ -117,7 +116,6 @@ export const makeTestAccount = async (
|
|||||||
accepted_dpa_version: d?.accepted_dpa_version ?? "1.0",
|
accepted_dpa_version: d?.accepted_dpa_version ?? "1.0",
|
||||||
email_verified: d?.email_verified ?? true,
|
email_verified: d?.email_verified ?? true,
|
||||||
auto_renew: d?.auto_renew ?? true,
|
auto_renew: d?.auto_renew ?? true,
|
||||||
license_alert: d?.license_alert ?? true,
|
|
||||||
notification: d?.notification ?? true,
|
notification: d?.notification ?? true,
|
||||||
encryption: d?.encryption ?? true,
|
encryption: d?.encryption ?? true,
|
||||||
encryption_password: d?.encryption_password ?? "password",
|
encryption_password: d?.encryption_password ?? "password",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user