diff --git a/package-lock.json b/package-lock.json index 10d1bc6..d98ebc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,11 +27,13 @@ "@types/react": "^18.0.18", "@types/react-dom": "^18.0.6", "@types/react-router-dom": "^5.3.3", + "axios": "^1.3.4", "craco": "^0.0.3", "dayjs": "^1.11.5", "formik": "^2.2.9", "moment": "^2.29.4", "nanoid": "^4.0.1", + "notistack": "^3.0.1", "numeral": "^2.0.6", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -6217,6 +6219,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -11767,6 +11792,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/goober": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.12.tgz", + "integrity": "sha512-yXHAvO08FU1JgTXX6Zn6sYCUFfB/OJSX8HHjDSgerZHZmFKAb08cykp5LBw5QnmyMcZyPRMqkdyHUSSzge788Q==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -15225,6 +15258,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/notistack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-3.0.1.tgz", + "integrity": "sha512-ntVZXXgSQH5WYfyU+3HfcXuKaapzAJ8fBLQ/G618rn3yvSzEbnOB8ZSOwhX+dAORy/lw+GC2N061JA0+gYWTVA==", + "dependencies": { + "clsx": "^1.1.0", + "goober": "^2.0.33" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/notistack" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -17482,6 +17536,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -26416,6 +26475,28 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.3.tgz", "integrity": "sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==" }, + "axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -30511,6 +30592,12 @@ "slash": "^3.0.0" } }, + "goober": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.12.tgz", + "integrity": "sha512-yXHAvO08FU1JgTXX6Zn6sYCUFfB/OJSX8HHjDSgerZHZmFKAb08cykp5LBw5QnmyMcZyPRMqkdyHUSSzge788Q==", + "requires": {} + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -32979,6 +33066,15 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, + "notistack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-3.0.1.tgz", + "integrity": "sha512-ntVZXXgSQH5WYfyU+3HfcXuKaapzAJ8fBLQ/G618rn3yvSzEbnOB8ZSOwhX+dAORy/lw+GC2N061JA0+gYWTVA==", + "requires": { + "clsx": "^1.1.0", + "goober": "^2.0.33" + } + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -34351,6 +34447,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", diff --git a/package.json b/package.json index 31a1361..cf77475 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,13 @@ "@types/react": "^18.0.18", "@types/react-dom": "^18.0.6", "@types/react-router-dom": "^5.3.3", + "axios": "^1.3.4", "craco": "^0.0.3", "dayjs": "^1.11.5", "formik": "^2.2.9", "moment": "^2.29.4", "nanoid": "^4.0.1", + "notistack": "^3.0.1", "numeral": "^2.0.6", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/index.tsx b/src/index.tsx index bd406da..6efa6e9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,8 +1,9 @@ import * as React from "react"; import CssBaseline from "@mui/material/CssBaseline"; +import { SnackbarProvider } from 'notistack'; import { ThemeProvider } from '@mui/material/styles'; import { createRoot } from 'react-dom/client'; -import { BrowserRouter, Routes, Route } from "react-router-dom"; +import { BrowserRouter, Routes, Route, Outlet, Navigate } from "react-router-dom"; import theme from "./theme"; import PublicRoute from "@kitUI/publicRoute"; import PrivateRoute from "@kitUI/privateRoute"; @@ -10,7 +11,7 @@ import Signin from "@pages/Authorization/signin"; import Signup from "@pages/Authorization/signup"; import Restore from "@pages/Authorization/restore"; import Sections from "@pages/Sections"; -import LoggedIn from "@pages/dashboard"; +import Dashboard from "@pages/dashboard"; import Error404 from "@pages/Error404"; import Users from "@pages/dashboard/Content/Users"; import Entities from "@pages/dashboard/Content/Entities"; @@ -34,23 +35,27 @@ root.render( - - - } /> - } /> - } /> - } /> - } /> - {componentsArray.map((e:any, i) => ( - {e[1]} } /> - ))} + + + + } /> + } /> + } /> + } /> + } /> + }> + {componentsArray.map((e:any, i) => ( + + ))} + - } - /> - - + } + /> + + + ); \ No newline at end of file diff --git a/src/kitUI/makeRequest.ts b/src/kitUI/makeRequest.ts new file mode 100644 index 0000000..bc9742d --- /dev/null +++ b/src/kitUI/makeRequest.ts @@ -0,0 +1,65 @@ +import axios from 'axios' + +interface MakeRequest { + method?: string + url: string + body?: unknown + useToken?: boolean + contentType?: boolean +} + +export default (props: MakeRequest) => { + return ( + new Promise(async (resolve, reject) => { + await makeRequest(props) + .then(r => resolve(r)) + .catch(r => reject(r)) + }) + ) +} + +function makeRequest({ + method = "post", + url, + body, + useToken = true, + contentType = false +}: MakeRequest) { + //В случае 401 рефреш должен попробовать вызваться 1 раз + let counterRefresh = true + let headers: any = {} + if (useToken) headers["Authorization"] = localStorage.getItem('AT') + if (contentType) headers["Content-Type"] = "application/json" + return axios({ + url: url, + method: method, + headers: headers, + data: body + }) + .then(response => { + if (response.data && response.data.accessToken) { + localStorage.setItem('AT', response.data.accessToken) + } + return response + }) + .catch(error => { + if (error.response.status == 401 && counterRefresh) { + refresh().then(response => { + if (response.data && response.data.accessToken) localStorage.setItem('AT', response.data.accessToken) + counterRefresh = false + }) + } else { + throw error + } + throw error + }) +} + +function refresh() { + return axios("https://hub.pena.digital/auth/refresh", { + headers: { + "Authorization": localStorage.getItem('AT'), + "Content-Type": "application/json" + } + }) +} \ No newline at end of file diff --git a/src/kitUI/privateRoute.tsx b/src/kitUI/privateRoute.tsx index 45f9975..2a64373 100644 --- a/src/kitUI/privateRoute.tsx +++ b/src/kitUI/privateRoute.tsx @@ -2,13 +2,11 @@ import * as React from "react"; import { useLocation, Navigate } from 'react-router-dom' export default ({ children }: any) => { - console.log("проверяю") - const auth = true const location = useLocation() - - if (!auth) { +//Если пользователь авторизован, перенаправляем его на нужный путь. Иначе выкидываем в регистрацию + if (localStorage.getItem('AT')) { return children } - return + return } diff --git a/src/kitUI/publicRoute.tsx b/src/kitUI/publicRoute.tsx index d0240cb..377b655 100644 --- a/src/kitUI/publicRoute.tsx +++ b/src/kitUI/publicRoute.tsx @@ -2,13 +2,11 @@ import * as React from "react"; import { useLocation, Navigate } from 'react-router-dom' export default ({ children }: any) => { - console.log("проверяю") - const auth = true const location = useLocation() - - if (!auth) { - return +//Если пользователь авторизован, перенаправляем его в приложение. Иначе пускаем куда хотел + if (localStorage.getItem('AT')) { + return } - return children + } diff --git a/src/pages/Authorization/restore.tsx b/src/pages/Authorization/restore.tsx index 17042f9..884bcb8 100644 --- a/src/pages/Authorization/restore.tsx +++ b/src/pages/Authorization/restore.tsx @@ -1,16 +1,19 @@ import * as React from "react"; +import { useNavigate } from "react-router-dom"; import { Formik, Field, Form } from 'formik'; import {useTheme} from "@mui/material/styles"; import { Link } from "react-router-dom" -import {Box, Button, Checkbox, TextField, Typography} from "@mui/material"; +import {Box, Typography} from "@mui/material"; import Logo from "@pages/Logo"; import CleverButton from "@kitUI/cleverButton" +import MakeRequest from "@kitUI/makeRequest"; import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import OutlinedInput from "@kitUI/outlinedInput"; export default () => { const theme = useTheme() + const navigate = useNavigate(); const [restore, setRestore] = React.useState(true) const [isReady, setIsReady] = React.useState(true) if (restore) { diff --git a/src/pages/Authorization/signin.tsx b/src/pages/Authorization/signin.tsx index 5783989..e80aef5 100644 --- a/src/pages/Authorization/signin.tsx +++ b/src/pages/Authorization/signin.tsx @@ -1,4 +1,6 @@ import * as React from "react" +import { useNavigate } from "react-router-dom"; +import { enqueueSnackbar } from 'notistack'; import {useTheme} from "@mui/material/styles" import { Formik, Field, Form } from 'formik' import { Link } from "react-router-dom" @@ -6,21 +8,56 @@ import { Box, Checkbox, TextField, Typography, FormControlLabel} from "@mui/mate import Logo from "@pages/Logo" import CleverButton from "@kitUI/cleverButton" import OutlinedInput from "@kitUI/outlinedInput" +import makeRequest from "@kitUI/makeRequest"; import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined" +interface Values { + email: string; + password: string; +} + +function validate(values: Values) { + const errors = {} as any; + if (!values.email) { + errors.email = "Required"; + } + if (!values.password) { + errors.password = "Required"; + } else if (!/^[\w-]{8,25}$/i.test(values.password)) { + errors.password = "Invalid password"; + } + return errors; +} export default () => { const theme = useTheme() + const navigate = useNavigate(); const [isReady, setIsReady] = React.useState(true) return( { - + makeRequest({ + url: "https://hub.pena.admin/auth/login", + body: { + "email": values.email, + "password": values.password + }, + useToken: false + }) + .then((e) => { + console.log(e) + navigate("/users") + }) + .catch((e) => { + console.log(e) + enqueueSnackbar(e.message ? e.message : `Unknown error`) + }) }} >
@@ -55,11 +92,11 @@ export default () => { *": {marginRight:"10px"}}}> - + *": {marginRight:"10px"}}}> - + { + const navigate = useNavigate(); const theme = useTheme() const [isReady, setIsReady] = React.useState(true) return( { + makeRequest({ + url: "https://hub.pena.admin/auth/register", + body: { + "login": "login", + "email": values.email, + "password": values.repeatPassword, + "phoneNumber": "+89999999999" + }, + useToken: false + }) + .then((e) => { + navigate("/users") + }) + .catch((e) => { + console.log(e) + enqueueSnackbar(e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error`) + }) }} > @@ -57,15 +98,15 @@ export default () => { *": {marginRight:"10px"}}}> - + *": {marginRight:"10px"}}}> - + *": {marginRight:"10px"}}}> - + У меня уже есть аккаунт diff --git a/src/pages/dashboard/Header/index.tsx b/src/pages/dashboard/Header/index.tsx index 8425177..fb6a75a 100644 --- a/src/pages/dashboard/Header/index.tsx +++ b/src/pages/dashboard/Header/index.tsx @@ -1,8 +1,9 @@ import * as React from "react"; -import { Box, Typography } from "@mui/material"; +import {Box, IconButton, Typography} from "@mui/material"; import theme from "../../../theme"; import ExitToAppOutlinedIcon from '@mui/icons-material/ExitToAppOutlined'; import Logo from "../../Logo"; +import makeRequest from "@kitUI/makeRequest"; const Header: React.FC = () => { @@ -43,7 +44,15 @@ const Header: React.FC = () => { Добро пожаловать, Администратор сервиса - { + makeRequest({ + url: "https://hub.pena.admin/auth/logout", + contentType: true + }) + .then(()=>localStorage.setItem('AT', "")) + }} + sx={{ display: "flex", flexDirection: "column", justifyContent: "center", @@ -55,7 +64,7 @@ const Header: React.FC = () => { color: theme.palette.golden.main, transform: "scale(1.3)" }} /> - + diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index d9e3654..69de9b8 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { Outlet } from 'react-router-dom' +import {Outlet} from 'react-router-dom' import {useTheme} from '@mui/material/styles'; import {Box} from "@mui/material"; import {ThemeProvider} from "@mui/material"; @@ -11,12 +11,7 @@ import ModalUser from "./ModalUser"; import ModalEntities from "./ModalEntities"; import {useMatch} from "react-router-dom"; - -export interface MWProps { - section: number -} - -const LoggedIn: React.FC = ({section}) => { +export default () => { const theme = useTheme() return ( @@ -41,7 +36,18 @@ const LoggedIn: React.FC = ({section}) => { justifyContent: "space-between", alignItems: "center" }}> - + + + @@ -49,10 +55,6 @@ const LoggedIn: React.FC = ({section}) => { - -) - ; + + ) } - - -export default LoggedIn; diff --git a/yarn.lock b/yarn.lock index 94bad94..72bf3dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3416,6 +3416,15 @@ "resolved" "https://registry.npmjs.org/axe-core/-/axe-core-4.6.3.tgz" "version" "4.6.3" +"axios@^1.3.4": + "integrity" "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==" + "resolved" "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz" + "version" "1.3.4" + dependencies: + "follow-redirects" "^1.15.0" + "form-data" "^4.0.0" + "proxy-from-env" "^1.1.0" + "axobject-query@^3.1.1": "integrity" "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==" "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" @@ -4173,7 +4182,7 @@ "process-nextick-args" "^2.0.0" "readable-stream" "^2.3.5" -"clsx@^1.0.2", "clsx@^1.2.1": +"clsx@^1.0.2", "clsx@^1.1.0", "clsx@^1.2.1": "integrity" "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" "resolved" "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" "version" "1.2.1" @@ -4742,7 +4751,7 @@ dependencies: "cssom" "~0.3.6" -"csstype@^3.0.2", "csstype@^3.1.1": +"csstype@^3.0.10", "csstype@^3.0.2", "csstype@^3.1.1": "integrity" "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" "resolved" "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz" "version" "3.1.1" @@ -6041,7 +6050,7 @@ "inherits" "^2.0.3" "readable-stream" "^2.3.6" -"follow-redirects@^1.0.0": +"follow-redirects@^1.0.0", "follow-redirects@^1.15.0": "integrity" "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" "version" "1.15.2" @@ -6086,6 +6095,15 @@ "combined-stream" "^1.0.8" "mime-types" "^2.1.12" +"form-data@^4.0.0": + "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" + "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "asynckit" "^0.4.0" + "combined-stream" "^1.0.8" + "mime-types" "^2.1.12" + "formik@^2.2.9": "integrity" "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==" "resolved" "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz" @@ -6336,6 +6354,11 @@ "merge2" "^1.4.1" "slash" "^3.0.0" +"goober@^2.0.33": + "integrity" "sha512-yXHAvO08FU1JgTXX6Zn6sYCUFfB/OJSX8HHjDSgerZHZmFKAb08cykp5LBw5QnmyMcZyPRMqkdyHUSSzge788Q==" + "resolved" "https://registry.npmjs.org/goober/-/goober-2.1.12.tgz" + "version" "2.1.12" + "gopd@^1.0.1": "integrity" "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==" "resolved" "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" @@ -8593,6 +8616,14 @@ "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" "version" "6.1.0" +"notistack@^3.0.1": + "integrity" "sha512-ntVZXXgSQH5WYfyU+3HfcXuKaapzAJ8fBLQ/G618rn3yvSzEbnOB8ZSOwhX+dAORy/lw+GC2N061JA0+gYWTVA==" + "resolved" "https://registry.npmjs.org/notistack/-/notistack-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "clsx" "^1.1.0" + "goober" "^2.0.33" + "npm-run-path@^4.0.1": "integrity" "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==" "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" @@ -9717,6 +9748,11 @@ "forwarded" "0.2.0" "ipaddr.js" "1.9.1" +"proxy-from-env@^1.1.0": + "integrity" "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "resolved" "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + "version" "1.1.0" + "prr@~1.0.1": "integrity" "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" "resolved" "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" @@ -9895,7 +9931,7 @@ "strip-ansi" "^6.0.1" "text-table" "^0.2.0" -"react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2 || ^18.0.0", "react-dom@^18.0.0", "react-dom@^18.2.0", "react-dom@>= 16.8.0", "react-dom@>=16.6.0", "react-dom@>=16.8": +"react-dom@^16.8.0 || ^17.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2 || ^18.0.0", "react-dom@^18.0.0", "react-dom@^18.2.0", "react-dom@>= 16.8.0", "react-dom@>=16.6.0", "react-dom@>=16.8": "integrity" "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==" "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" "version" "18.2.0"