From d27d3a163224a61d0b8047f619a0e59f28f6a5dc Mon Sep 17 00:00:00 2001 From: goodm2ice Date: Wed, 29 Dec 2021 17:48:10 +0500 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B0=D0=BC=D0=B8=20=D0=B8=20=D1=85=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BB=D0=B8=D1=89=D0=B5=D0=BC=20=D0=94=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BE=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B0=D0=B9=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 3 +- src/App.js | 2 +- src/components/ChangePassword.tsx | 5 +-- src/components/Private/PrivateContent.tsx | 4 +-- src/components/Private/PrivateMenuItem.tsx | 2 +- src/components/Private/PrivateRoute.tsx | 5 +-- src/components/Table/EditableCell.tsx | 1 - src/components/UserMenu.tsx | 13 +++---- src/components/factory.ts | 5 +-- src/pages/AdminPanel/index.jsx | 2 +- src/pages/Documents/index.jsx | 2 +- src/pages/Login.jsx | 11 ++---- src/pages/Main.jsx | 2 +- .../{PermissionService.ts => permissions.ts} | 12 ++----- src/utils/storage.ts | 36 +++++++++++++++++++ 15 files changed, 64 insertions(+), 41 deletions(-) rename src/utils/{PermissionService.ts => permissions.ts} (79%) diff --git a/public/index.html b/public/index.html index 5ab8445..4eccf76 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ АСБ Vision @@ -17,3 +17,4 @@
+ц \ No newline at end of file diff --git a/src/App.js b/src/App.js index f420b63..6531f77 100644 --- a/src/App.js +++ b/src/App.js @@ -12,7 +12,7 @@ import { OpenAPI } from './services/api' import { PrivateRoute } from './components/Private' //OpenAPI.BASE = 'http://localhost:3000' -OpenAPI.TOKEN = localStorage['token'] +OpenAPI.TOKEN = localStorage.getItem('token') OpenAPI.HEADERS = {'Content-Type': 'application/json'} export default function App() { diff --git a/src/components/ChangePassword.tsx b/src/components/ChangePassword.tsx index edf4db3..d5b9334 100644 --- a/src/components/ChangePassword.tsx +++ b/src/components/ChangePassword.tsx @@ -8,6 +8,7 @@ import { passwordRules, createPasswordRules } from '../utils/validationRules' import LoaderPortal from './LoaderPortal' import { invokeWebApiWrapperAsync } from './factory' import { UserView } from './Views' +import { getUserId, getUserLogin } from '../utils/storage' const formLayout: FormProps = { labelCol: { span: 11 }, wrapperCol: { span: 16 } } @@ -38,11 +39,11 @@ export const ChangePassword = memo(({ user, visible, onCanc const onFormFinish = () => invokeWebApiWrapperAsync( async() => { - await AuthService.changePassword(user?.id ?? localStorage['userId'], `"${password}"`) + await AuthService.changePassword(user?.id ?? getUserId() ?? -1, `"${password}"`) onOk?.() }, setShowLoader, - `Не удалось сменить пароль пользователя ${localStorage['login']}` + `Не удалось сменить пароль пользователя ${getUserLogin()}` ) return ( diff --git a/src/components/Private/PrivateContent.tsx b/src/components/Private/PrivateContent.tsx index 404f9c7..c10810e 100644 --- a/src/components/Private/PrivateContent.tsx +++ b/src/components/Private/PrivateContent.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Role, Permission, hasPermission, isInRole } from '../../utils/PermissionService' +import { Role, Permission, hasPermission, isInRole } from '../../utils/permissions' type PrivateContentProps = { roles?: Role[] | Role @@ -8,4 +8,4 @@ type PrivateContentProps = { } export const PrivateContent: React.FC = ({ permission, roles, children = null }) => - hasPermission(permission) || isInRole(roles) ? children : null + hasPermission(permission) && isInRole(roles) ? children : null diff --git a/src/components/Private/PrivateMenuItem.tsx b/src/components/Private/PrivateMenuItem.tsx index e764522..b62d2ef 100644 --- a/src/components/Private/PrivateMenuItem.tsx +++ b/src/components/Private/PrivateMenuItem.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Menu } from 'antd' -import { Role, Permission, hasPermission, isInRole } from '../../utils/PermissionService' +import { Role, Permission, hasPermission, isInRole } from '../../utils/permissions' type PrivateMenuItemProps = { diff --git a/src/components/Private/PrivateRoute.tsx b/src/components/Private/PrivateRoute.tsx index fa098bc..c187cbf 100644 --- a/src/components/Private/PrivateRoute.tsx +++ b/src/components/Private/PrivateRoute.tsx @@ -1,7 +1,8 @@ import React from 'react' import { StaticContext } from 'react-router' import { Route, Redirect, RouteComponentProps } from 'react-router-dom' -import { Role, Permission, hasPermission, isInRole } from '../../utils/PermissionService' +import { Role, Permission, hasPermission, isInRole } from '../../utils/permissions' +import { getUserToken } from '../../utils/storage' type PrivateRouteProps = { roles: Role[] | Role @@ -12,7 +13,7 @@ type PrivateRouteProps = { } export const PrivateRoute: React.FC = ({ permission, roles, component, children, ...other }) => { - const available = localStorage.getItem('token') && (hasPermission(permission) || isInRole(roles)) + const available = getUserToken() && (hasPermission(permission) && isInRole(roles)) return ( { - localStorage.removeItem('login') - localStorage.removeItem('token') -} - type UserMenuProps = { isAdmin?: boolean } @@ -36,7 +33,7 @@ export const UserMenu: React.FC = ({ isAdmin }) => { placement={'bottomRight'} overlay={( - + {isAdmin ? ( Вернуться на сайт ) : ( @@ -47,12 +44,12 @@ export const UserMenu: React.FC = ({ isAdmin }) => { Сменить пароль - Выход + Выход )} > - + { const response = await fetch(url, { headers: { - Authorization: `Bearer ${localStorage['token']}` + Authorization: `Bearer ${getUserToken()}` }, method: 'Get' }) @@ -83,7 +84,7 @@ export const download = async (url: string, fileName?: string) => { export const upload = async (url: string, formData: FormData) => { const response = await fetch(url, { headers: { - Authorization: `Bearer ${localStorage['token']}` + Authorization: `Bearer ${getUserToken()}` }, method: 'Post', body: formData, diff --git a/src/pages/AdminPanel/index.jsx b/src/pages/AdminPanel/index.jsx index 484b69c..1a55ea4 100644 --- a/src/pages/AdminPanel/index.jsx +++ b/src/pages/AdminPanel/index.jsx @@ -59,7 +59,7 @@ export const AdminPanel = () => { - + diff --git a/src/pages/Documents/index.jsx b/src/pages/Documents/index.jsx index 08a3c63..c2c72cd 100644 --- a/src/pages/Documents/index.jsx +++ b/src/pages/Documents/index.jsx @@ -4,7 +4,7 @@ import { Layout, Menu } from 'antd' import { FolderOutlined } from '@ant-design/icons' import { Switch, useParams, Link, Route } from 'react-router-dom' import { PrivateMenuItem } from '../../components/Private' -import { isInRole } from '../../utils/PermissionService' +import { isInRole } from '../../utils/permissions' import DocumentsTemplate from './DocumentsTemplate' const { Content } = Layout diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 46af033..ad72bea 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -2,23 +2,18 @@ import { Card, Form, Input, Button } from 'antd' import { UserOutlined, LockOutlined } from '@ant-design/icons' import { useState } from 'react' import { Link, useHistory } from 'react-router-dom' -import { AuthService, OpenAPI } from '../services/api/' + +import { AuthService } from '../services/api/' import LoaderPortal from '../components/LoaderPortal' import { invokeWebApiWrapperAsync } from '../components/factory' import { loginRules, passwordRules } from '../utils/validationRules' +import { setUser } from '../utils/storage' import '../styles/index.css' import logo from '../images/logo_32.png' const logoIcon = {'АСБ'} -const setUser = (user) => { - OpenAPI.TOKEN = user.token - localStorage['userId'] = user.id - localStorage['token'] = user.token - localStorage['login'] = user.login -} - export default function Login() { const history = useHistory() const [showLoader, setShowLoader] = useState(false) diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx index 78b83d7..951b780 100644 --- a/src/pages/Main.jsx +++ b/src/pages/Main.jsx @@ -8,7 +8,7 @@ import AdminPanel from './AdminPanel' export const Main = () => ( - + diff --git a/src/utils/PermissionService.ts b/src/utils/permissions.ts similarity index 79% rename from src/utils/PermissionService.ts rename to src/utils/permissions.ts index 2815c78..2da9dc8 100644 --- a/src/utils/PermissionService.ts +++ b/src/utils/permissions.ts @@ -1,18 +1,12 @@ -import { getArrayFromLocalStorage } from './storage' +import { getUserPermissions, getUserRoles } from './storage' export type Role = string export type Permission = string -export const getUserRoles = (): Role[] => getArrayFromLocalStorage('roles') ?? [] -export const getUserPermissions = (): Permission[] => - getArrayFromLocalStorage('permissions') ?? [] - export const hasPermission = (permission?: Permission): boolean => { if (typeof permission !== 'string') return true - if (localStorage.getItem('login') === 'dev') return true // TODO: Удалить строку - - return permission in getUserPermissions() + return getUserPermissions().includes(permission) } export const isInRole = (roles?: Role[] | Role): boolean => { @@ -20,8 +14,6 @@ export const isInRole = (roles?: Role[] | Role): boolean => { roles = [roles] if (!roles?.length) return true - if (localStorage.getItem('login') === 'dev') return true // TODO: Удалить строку - const user_roles = getUserRoles() return roles.some((role) => role in user_roles) } diff --git a/src/utils/storage.ts b/src/utils/storage.ts index a9c99d2..aca5a45 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -1,5 +1,41 @@ +import { OpenAPI, UserTokenDto } from '../services/api' +import { Role, Permission } from './permissions' + +export enum StorageNames { + userId = 'userId', + token = 'token', + login = 'login', + permissions = 'permissions', + roles = 'roles', +} + export const getArrayFromLocalStorage = (name: string, sep: string | RegExp = ','): T[] | null => { const raw = localStorage.getItem(name) if (!raw) return null return raw.split(sep).map(elm => elm as T) } + +export const getUserRoles = (): Role[] => getArrayFromLocalStorage(StorageNames.roles) ?? [] +export const getUserPermissions = (): Permission[] => getArrayFromLocalStorage(StorageNames.permissions) ?? [] +export const getUserId = () => Number(localStorage.getItem(StorageNames.userId)) || null +export const getUserLogin = () => localStorage.getItem(StorageNames.login) +export const getUserToken = () => localStorage.getItem(StorageNames.token) + +export const setUser = (user: UserTokenDto) => { + OpenAPI.TOKEN = user.token ?? undefined + localStorage.setItem(StorageNames.userId, String(user.id)) + localStorage.setItem(StorageNames.token, String(user.token)) + localStorage.setItem(StorageNames.login, String(user.login)) + if (user.permissions) + localStorage.setItem(StorageNames.permissions, user.permissions.map((permission) => permission.name).join(',')) + if (user.roleNames) + localStorage.setItem(StorageNames.roles, user.roleNames.join(',')) +} + +export const removeUser = () => { + localStorage.removeItem(StorageNames.userId) + localStorage.removeItem(StorageNames.login) + localStorage.removeItem(StorageNames.token) + localStorage.removeItem(StorageNames.permissions) + localStorage.removeItem(StorageNames.roles) +}