saito.k deb3431d74 Merged PR 531: 画面実装(代行操作)
## 概要
[Task2909: 画面実装(代行操作)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2909)

- ディーラーユーザーが代行操作用トークンを取得して、第五階層ユーザーの代行操作ができる実装をしました。
  - 代行後に各対象タブが代行操作デザインで表示され、代行対象として操作できるようになっています。
    - 各APIの呼び出しについて代行操作用トークンがあればそちらを使うように実装しています。
 - 代行操作のタブ、ページ移動時に代行操作を維持するために遷移をリンクから`useNavigate`に変更しました。

## レビューポイント
- 代行操作用トークンの取り扱いについて
  - APIからのトークン取得後、`store.auth`に代行操作用トークンを保存し、利用時には関数を使って間接的に呼でいますが構成として不自然な点はないでしょうか?
    - トークン取得関数では代行操作用トークンがあればそれを、なければ通常のトークンを取得するようにしています。
      - これはAPIのトークンを設定する際にトークンを取得側では代行操作中か意識せずに一つの関数を呼べばいいようにするためです。
  - 代行操作用トークンの保存は通常のトークン保存と同様に`operation`から`Slice`に設定したSet関数を呼ぶことでstateに保存していますが、使い方として気になることはないでしょうか?

※代行操作中に表示するタブの制限と代行操作トークンの更新処理は別タスクでの実施予定です。

## UIの変更
- [Task2909](https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task2909?csf=1&web=1&e=TnwgOb)

## 動作確認状況
- ローカルで確認
2023-11-06 08:28:40 +00:00

137 lines
3.7 KiB
TypeScript

import { ConfigurationParameters } from "api";
import { decodeToken } from "../../common/decodeToken";
import { ADMIN_ROLES, USER_ROLES } from "../../components/auth/constants";
import type { AuthState } from "./state";
/**
* Get access token
* @returns access token
*/
export const loadAccessToken = (): string | null =>
localStorage.getItem("accessToken");
/**
* Set access token
* @param accessToken
*/
export const saveAccessToken = (accessToken: string): void => {
localStorage.setItem("accessToken", accessToken);
};
/**
* Remove access token
*/
export const removeAccessToken = (): void => {
localStorage.removeItem("accessToken");
};
/**
* Get refresh token
* @returns refresh token
*/
export const loadRefreshToken = (): string | null =>
localStorage.getItem("refreshToken");
/**
* Set refresh token
* @param refreshToken
*/
export const saveRefreshToken = (refreshToken: string): void => {
localStorage.setItem("refreshToken", refreshToken);
};
/**
* Remove refresh token
*/
export const removeRefreshToken = (): void => {
localStorage.removeItem("refreshToken");
};
/**
* 代行操作用のアクセストークンを持っている場合はそれを返す
* なければ通常のアクセストークンを返す
* @returns access token
*/
export const getAccessToken = (state: AuthState): string | null =>
state.delegationAccessToken ?? state.accessToken;
/**
* 代行操作用のリフレッシュトークンを持っている場合はそれを返す
* なければ通常のリフレッシュトークンを返す
* @returns refresh token
*/
export const getRefreshToken = (state: AuthState): string | null =>
state.delegationRefreshToken ?? state.refreshToken;
// 初期状態のAPI Config
export const initialConfig = (): ConfigurationParameters => {
const config: ConfigurationParameters = {};
if (import.meta.env.VITE_STAGE === "local") {
config.basePath = "http://localhost:8081";
} else {
config.basePath = `${window.location.origin}/dictation/api`;
}
return config;
};
/**
* is admin user ログインしているユーザがadmin権限を持つかどうかを返す
* @returns bool
*/
export const isAdminUser = (): boolean => {
const jwt = loadAccessToken();
const token = jwt ? decodeToken(jwt) : null;
if (!token) {
return false;
}
return token.role.includes(ADMIN_ROLES.ADMIN);
};
/**
* is standard user ログインしているユーザがstandard権限を持つかどうかを返す
* @returns bool
*/
// TODO 上記の関数とまとめて汎用的な関数にリファクタリングする
export const isStandardUser = (): boolean => {
const jwt = loadAccessToken();
const token = jwt ? decodeToken(jwt) : null;
if (!token) {
return false;
}
return token.role.includes(ADMIN_ROLES.STANDARD);
};
/**
* is author user ログインしているユーザがAuthorかどうかを返す
* @returns bool
*/
export const isAuthorUser = (): boolean => {
const jwt = loadAccessToken();
const token = jwt ? decodeToken(jwt) : null;
if (!token) {
return false;
}
return token.role.includes(USER_ROLES.AUTHOR);
};
/**
* is approve tier ログインしているアカウントの階層を確認したのち返す
* @returns bool
*/
export const isApproveTier = (tiers: string[]): boolean => {
const jwt = loadAccessToken();
const token = jwt && decodeToken(jwt);
return !!token && tiers.includes(token.tier.toString());
};
/**
* is typist user ログインしているユーザがTypistかどうかを返す
* @returns bool
*/
export const isTypistUser = (): boolean => {
const jwt = loadAccessToken();
const token = jwt ? decodeToken(jwt) : null;
if (!token) {
return false;
}
return token.role.includes(USER_ROLES.TYPIST);
};