diff --git a/client/config/webpack.dev.js b/client/config/webpack.dev.js
index c79eeaa..3bfa20a 100644
--- a/client/config/webpack.dev.js
+++ b/client/config/webpack.dev.js
@@ -8,9 +8,18 @@ const common = require('./webpack.common.js')
module.exports = merge(common, {
// Set the mode to development or production
mode: 'development',
- watch: true,
- watchOptions: {
- ignored: '**/node_modules/',
+ // watch: true,
+ // watchOptions: {
+ // ignored: '**/node_modules/',
+ // },
+
+ devServer: {
+ // watchOptions: {
+ // ignored: '**/node_modules/'
+ // },
+ client: {
+ webSocketURL: 'auto://0.0.0.0:0/ws'
+ },
},
// Control how source maps are generated
diff --git a/client/package.json b/client/package.json
index 9c9e788..4212c53 100644
--- a/client/package.json
+++ b/client/package.json
@@ -3,6 +3,10 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@emotion/react": "^11.11.1",
+ "@emotion/styled": "^11.11.0",
+ "@mui/base": "^5.0.0-beta.8",
+ "@mui/material": "^5.14.2",
"@types/node": "^16.18.39",
"@types/react": "^18.2.16",
"@types/react-dom": "^18.2.7",
@@ -10,6 +14,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
+ "sass": "^1.64.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
@@ -26,7 +31,10 @@
]
},
"devDependencies": {
+ "css-loader": "^6.8.1",
"html-webpack-plugin": "^5.5.3",
+ "sass-loader": "^13.3.2",
+ "style-loader": "^3.3.3",
"ts-loader": "^9.4.4",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
diff --git a/client/src/App.tsx b/client/src/App.tsx
index a53698a..ebeb59d 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,26 +1,31 @@
import React from 'react';
import logo from './logo.svg';
-import './App.css';
+import { createTheme, ThemeProvider } from '@mui/material/styles';
+import { yellow} from "@mui/material/colors";
+import './sass/index.scss';
+
+const theme = createTheme({
+ palette:{
+ primary: yellow,
+ mode: "dark"
+ }
+})
+
+import ModePanel from "./components/modePanel";
function App() {
return (
-
+
+
+
);
}
-export default App;
+export default App;
\ No newline at end of file
diff --git a/client/src/components/groups/groupPanel.tsx b/client/src/components/groups/groupPanel.tsx
new file mode 100644
index 0000000..c13230a
--- /dev/null
+++ b/client/src/components/groups/groupPanel.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import {useState, useEffect} from "react";
+
+import Table from '@mui/material/Table';
+import TableBody from '@mui/material/TableBody';
+import TableCell from '@mui/material/TableCell';
+import TableRow from "@mui/material/TableRow";
+import TableContainer from '@mui/material/TableContainer';
+import TableHead from '@mui/material/TableHead';
+import Typography from "@mui/material/Typography";
+
+import GroupRow from "./groupRow";
+
+export default function GroupPanel({
+ groups
+}){
+
+ return(
+
+
+
+
+
+ Group
+ Created At
+ Invite Token
+
+
+
+ {groups ? groups.map((group) => (
+
+ )) : undefined}
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/client/src/components/groups/groupRow.tsx b/client/src/components/groups/groupRow.tsx
new file mode 100644
index 0000000..faf5ac2
--- /dev/null
+++ b/client/src/components/groups/groupRow.tsx
@@ -0,0 +1,29 @@
+import TableCell from '@mui/material/TableCell';
+import TableContainer from '@mui/material/TableContainer';
+import TableHead from '@mui/material/TableHead';
+import TableRow from '@mui/material/TableRow';
+
+export interface GroupRowProps {
+ name: string;
+ id: string;
+ invite_token: string;
+ created_at: string;
+}
+
+export default function GroupRow(
+ {name, id, invite_token, created_at}: GroupRowProps
+){
+ return(
+
+
+ {name}
+
+ {created_at}
+ {invite_token}
+
+ )
+
+}
\ No newline at end of file
diff --git a/client/src/components/modePanel.tsx b/client/src/components/modePanel.tsx
new file mode 100644
index 0000000..05e9fba
--- /dev/null
+++ b/client/src/components/modePanel.tsx
@@ -0,0 +1,44 @@
+import * as React from 'react';
+
+import Tab from '@mui/material/Tab';
+import TabsList from '@mui/base/TabsList';
+import Tabs from '@mui/material/Tabs';
+import Box from "@mui/material/Box";
+import { styled } from '@mui/material/styles';
+
+import ManagePanel from "./panels/managePanel";
+import JoinPanel from "./panels/joinPanel";
+import TabPanel from "./tabPanel";
+
+const StyledTabs = styled(Tabs)({
+ '& .MuiTabs-indicator': {
+ backgroundColor: "#DED03A"
+ }
+})
+
+export default function ModePanel() {
+ const [value, setValue] = React.useState(0);
+
+ const handleChange = (event, newValue) => {
+ setValue(newValue);
+ };
+
+ return (
+
+
+ {/**/}
+
+
+ {/* */}
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/components/panels/joinPanel.tsx b/client/src/components/panels/joinPanel.tsx
new file mode 100644
index 0000000..14d438e
--- /dev/null
+++ b/client/src/components/panels/joinPanel.tsx
@@ -0,0 +1,9 @@
+
+
+export default function JoinPanel(){
+ return(
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/client/src/components/panels/managePanel.tsx b/client/src/components/panels/managePanel.tsx
new file mode 100644
index 0000000..9020e8c
--- /dev/null
+++ b/client/src/components/panels/managePanel.tsx
@@ -0,0 +1,144 @@
+import React from 'react';
+import {useState, useEffect} from "react";
+import TextField from '@mui/material/TextField';
+import Button from '@mui/material/Button';
+
+import GroupPanel from "../groups/groupPanel";
+
+export default function ManagePanel(){
+ const [loggedIn, setLoggedIn] = useState(false);
+ const [authError, setAuthError] = useState(false);
+ const [errorText, setErrorText] = useState('');
+ const [text, setText] = useState('');
+ const [groups, setGroups] = useState([]);
+
+
+ const submitToken = (login_type) => {
+ fetch("api/auth", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify({
+ token: text
+ })
+ }).then(
+ result => result.json()
+ ).then(
+ response => {
+
+ if (response.status !== "success"){
+ if (login_type === 'initial') {
+ // Do nothing, we're just checking
+ return
+ }
+ setAuthError(true)
+ setLoggedIn(false)
+ setErrorText(response.message)
+ console.log('failed')
+ } else if (response.status === "success") {
+ setLoggedIn(true)
+ setAuthError(false)
+ setErrorText('')
+ console.log('succeeded')
+ }
+ console.log(response)
+ }
+ )
+ }
+
+ const fetchGroups = () => {
+ fetch('api/groups')
+ .then(res => res.json())
+ .then(res => {
+ console.log('fetched groups', res)
+ if (res.data !== undefined) {
+ setGroups(res.data)
+ }
+ })
+ }
+
+ const createGroup = () => {
+ fetch("api/groups", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify({
+ name: text,
+ enable: true
+ })
+ })
+ .then(req => req.json())
+ .then(req => {
+ console.log(req)
+ if (req.status === "success"){
+ setAuthError(false);
+ setErrorText('');
+ setGroups([...groups, req.data])
+ } else {
+ setAuthError(true);
+ setErrorText(req.message);
+ }
+ })
+ }
+
+ const handleClick = () => {
+ if (!loggedIn){
+ submitToken('');
+ } else {
+ createGroup();
+ }
+ }
+
+
+ const textChanged = (event: React.ChangeEvent) => {
+ setText(event.target.value)
+ }
+
+ // Call auth once when loaded to check session cookie
+ useEffect(() => {
+ submitToken('initial')
+ }, [])
+
+ // Fetch groups if we're logged in
+ useEffect(() => {
+ if (loggedIn) {
+ console.log('fetching groups')
+ fetchGroups()
+ }
+ }, [loggedIn])
+
+ return(
+
+
+
+
+ Submit
+
+
+ {
+ loggedIn ?
+
+ :
+ null
+ }
+
+ )
+}
\ No newline at end of file
diff --git a/client/src/components/tabPanel.tsx b/client/src/components/tabPanel.tsx
new file mode 100644
index 0000000..af3c6aa
--- /dev/null
+++ b/client/src/components/tabPanel.tsx
@@ -0,0 +1,30 @@
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import Typography from '@mui/material/Typography';
+import Box from '@mui/material/Box';
+
+export default function TabPanel(props) {
+ const { children, value, index, ...other } = props;
+
+ return (
+
+ {value === index && (
+
+ {children}
+
+ )}
+
+ );
+}
+
+TabPanel.propTypes = {
+ children: PropTypes.node,
+ index: PropTypes.number.isRequired,
+ value: PropTypes.number.isRequired,
+};
\ No newline at end of file
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 032464f..5d6db87 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -1,8 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
-import './index.css';
+import './sass/index.scss';
import App from './App';
-import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
@@ -13,7 +12,3 @@ root.render(
);
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
diff --git a/client/src/react-app-env.d.ts b/client/src/react-app-env.d.ts
deleted file mode 100644
index 6431bc5..0000000
--- a/client/src/react-app-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/client/src/reportWebVitals.ts b/client/src/reportWebVitals.ts
deleted file mode 100644
index 49a2a16..0000000
--- a/client/src/reportWebVitals.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { ReportHandler } from 'web-vitals';
-
-const reportWebVitals = (onPerfEntry?: ReportHandler) => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry);
- getFID(onPerfEntry);
- getFCP(onPerfEntry);
- getLCP(onPerfEntry);
- getTTFB(onPerfEntry);
- });
- }
-};
-
-export default reportWebVitals;
diff --git a/client/src/App.css b/client/src/sass/App.scss
similarity index 55%
rename from client/src/App.css
rename to client/src/sass/App.scss
index 74b5e05..e7d8353 100644
--- a/client/src/App.css
+++ b/client/src/sass/App.scss
@@ -1,7 +1,31 @@
.App {
- text-align: center;
+ //text-align: center;
+ background-color: $color-background;
+ //width: 100%;
+ //height: 100%;
+ //margin: {
+ // top: 5%;
+ // left: 10%;
+ // right: 10%;
+ // bottom: 5%;
+ //}
+ border: 2px solid $color-primary;
+ height:100%;
}
+.App-Container {
+ padding: {
+ top: 5%;
+ left: 10%;
+ right: 10%;
+ bottom: 5%;
+ }
+ width:100%;
+ height:100%;
+ box-sizing: border-box;
+}
+
+
.App-logo {
height: 40vmin;
pointer-events: none;
@@ -14,8 +38,10 @@
}
.App-header {
- background-color: #282c34;
- min-height: 100vh;
+ text-align: center;
+ margin: {
+ top: 1em;
+ }
display: flex;
flex-direction: column;
align-items: center;
diff --git a/client/src/index.css b/client/src/sass/base.scss
similarity index 57%
rename from client/src/index.css
rename to client/src/sass/base.scss
index ec2585e..3388e7e 100644
--- a/client/src/index.css
+++ b/client/src/sass/base.scss
@@ -1,13 +1,20 @@
body {
+ background-color: $color-background;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+#root {
+ width:100%;
+ height:100%;
+ position:absolute;
+}
+
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+ monospace;
}
diff --git a/client/src/sass/index.scss b/client/src/sass/index.scss
new file mode 100644
index 0000000..d766cdb
--- /dev/null
+++ b/client/src/sass/index.scss
@@ -0,0 +1,7 @@
+@charset "utf-8";
+
+@import './variables.scss';
+@import './base.scss';
+@import './App.scss';
+@import './tabs.scss';
+@import './input.scss';
\ No newline at end of file
diff --git a/client/src/sass/input.scss b/client/src/sass/input.scss
new file mode 100644
index 0000000..22501ef
--- /dev/null
+++ b/client/src/sass/input.scss
@@ -0,0 +1,50 @@
+.InputSlot {
+ min-width: 320px;
+ width: 100%;
+ padding: 8px 12px;
+ box-sizing: border-box;
+}
+
+.Panel .Input {
+ width: 100%;
+}
+
+.InputGroup {
+ display: flex;
+ flex-direction: row;
+ gap: 2em;
+ align-items: flex-start;
+
+
+
+ .Input {
+ flex-basis: 70%;
+ }
+
+ .MuiButton-root {
+ flex-basis: 30%;
+ flex-grow:0;
+ height: 56px;
+ }
+
+}
+
+//.MuiButton-root {
+// font-family: IBM Plex Sans, sans-serif;
+// font-weight: 600;
+// font-size: 0.875rem;
+// line-height: 1.5;
+// background-color: $color-primary;
+// padding: 8px 16px;
+// border-radius: 8px;
+// color: black;
+// transition: all 150ms ease;
+// cursor: pointer;
+// border: none;
+// box-shadow: 0px 4px 30px black;
+//
+// &:hover{
+// background-color: $color-primary-darker;
+// }
+//
+//}
\ No newline at end of file
diff --git a/client/src/sass/tabs.scss b/client/src/sass/tabs.scss
new file mode 100644
index 0000000..b0f9052
--- /dev/null
+++ b/client/src/sass/tabs.scss
@@ -0,0 +1,45 @@
+
+.ModePanel {
+ max-width: 80%;
+ margin: auto;
+
+ .TabsList {
+ min-width: 400px;
+ background-color: transparent;
+ border-radius: 12px;
+ margin: {
+ top: 12px;
+ bottom: 12px;
+ left: auto;
+ right: auto;
+ }
+ border: 5px solid $color-primary;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ align-content: space-between;
+
+ .Tab {
+ font-family: 'IBM Plex Sans', sans-serif;
+ color: white;
+ cursor: pointer;
+ font-size: 1.5rem;
+ font-weight: bold;
+ background-color: transparent;
+ width: 100%;
+ line-height: 1.5;
+ padding: 8px 12px;
+ margin: 6px;
+ border-radius: 8px;
+ display: flex;
+ justify-content: center;
+ border: none;
+ }
+
+ .Tab.Mui-selected {
+ background-color: $color-primary;
+ color: $color-background;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/client/src/sass/variables.scss b/client/src/sass/variables.scss
new file mode 100644
index 0000000..53cc0bf
--- /dev/null
+++ b/client/src/sass/variables.scss
@@ -0,0 +1,4 @@
+$color-primary: #DED03A;
+$color-primary-darker: scale-color($color-primary, $lightness: -10%);
+$color-secondary: #A167A5;
+$color-background: #1C1B22;
\ No newline at end of file
diff --git a/client/src/setupTests.ts b/client/src/setupTests.ts
deleted file mode 100644
index 8f2609b..0000000
--- a/client/src/setupTests.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
diff --git a/client/src/types.d.ts b/client/src/types.d.ts
new file mode 100644
index 0000000..b623f68
--- /dev/null
+++ b/client/src/types.d.ts
@@ -0,0 +1,5 @@
+
+declare module "*.svg" {
+ const content: any;
+ export default content;
+}
diff --git a/client/tsconfig.json b/client/tsconfig.json
index 84cef4f..6e118eb 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -17,6 +17,6 @@
"esModuleInterop": true
},
"include": [
- "src"
+ "src", "src/types.d.ts"
]
}
diff --git a/server/config/custom-environment-variables.ts b/server/config/custom-environment-variables.ts
index 13c0a50..66809a3 100755
--- a/server/config/custom-environment-variables.ts
+++ b/server/config/custom-environment-variables.ts
@@ -12,5 +12,9 @@ export default {
client_secret: 'SLACK_CLIENT_SECRET',
signing_secret: 'SLACK_SIGNING_SECRET'
},
- admin_token: 'ADMIN_TOKEN'
+ admin_token: 'ADMIN_TOKEN',
+ cookies:{
+ key1: 'COOKIE_KEY_1',
+ key2: 'COOKIE_KEY_2'
+ }
}
\ No newline at end of file
diff --git a/server/package.json b/server/package.json
index 65e3ae4..dcc5a6c 100644
--- a/server/package.json
+++ b/server/package.json
@@ -18,6 +18,7 @@
"dependencies": {
"@slack/oauth": "^2.6.1",
"config": "^3.3.9",
+ "cookie-session": "^2.0.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
@@ -34,6 +35,7 @@
},
"devDependencies": {
"@types/config": "^3.3.0",
+ "@types/cookie-session": "^2.0.44",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2",
diff --git a/server/src/app.ts b/server/src/app.ts
index 727a282..509b646 100644
--- a/server/src/app.ts
+++ b/server/src/app.ts
@@ -7,8 +7,10 @@ import cors from 'cors';
import { AppDataSource } from './db/data-source';
import AppError from './errors/appError';
+import {cookieMiddleware} from "./middleware/cookies";
import groupRoutes from "./routes/group.routes";
import slackRoutes from "./routes/slack.routes";
+import authRoutes from "./routes/auth.routes";
@@ -17,6 +19,7 @@ AppDataSource.initialize()
const app = express();
app.use(express.json({limit: "10kb"}));
+ app.use(cookieMiddleware);
app.get('/healthcheck', async (_, res: Response) => {
res.status(200).json({
@@ -25,6 +28,7 @@ AppDataSource.initialize()
})
app.use('/groups', groupRoutes);
+ app.use('/auth', authRoutes)
// app.use('/slack', async (req:Request, res:Response) => {
// console.log(req)
diff --git a/server/src/auth.ts b/server/src/auth.ts
new file mode 100644
index 0000000..f1056c7
--- /dev/null
+++ b/server/src/auth.ts
@@ -0,0 +1,20 @@
+import config from 'config';
+import {createHash} from "crypto";
+import AppError from "./errors/appError";
+
+export const tokenHasher = (token:string) => {
+ if (token === undefined){
+ return ''
+ }
+
+ let hash = createHash('blake2b512');
+ hash.update(token);
+ return hash.digest('hex');
+}
+
+const admin_token = config.get('admin_token');
+export const hashed_token = tokenHasher(admin_token)
+
+if (hashed_token === ""){
+ throw new Error('Hashed admin token cannot be empty')
+}
\ No newline at end of file
diff --git a/server/src/controllers/auth.controller.ts b/server/src/controllers/auth.controller.ts
new file mode 100644
index 0000000..b03f519
--- /dev/null
+++ b/server/src/controllers/auth.controller.ts
@@ -0,0 +1,32 @@
+import {NextFunction, Request, Response} from 'express';
+import {CheckAdminInput} from "../schemas/auth.schema";
+import { hashed_token, tokenHasher} from "../auth";
+
+
+
+
+export const checkAdminToken = async(
+ req: Request<{},{},CheckAdminInput>,
+ res: Response
+) => {
+ let hashed_user_token = tokenHasher(req.body?.token)
+
+ if (hashed_user_token === hashed_token ||
+ req.session?.hashed_token === hashed_token
+ ){
+ req.session.hashed_token = hashed_token;
+ console.log("Logged in with admin token")
+ res.status(200).json({
+ status: 'success',
+ message: "Correct admin token!"
+ });
+ } else {
+ req.session.logged_in = false;
+
+ console.log("Login with admin token failed")
+ return res.status(403).json({
+ status:'fail',
+ message: "Incorrect admin token!"
+ })
+ }
+}
diff --git a/server/src/controllers/group.controller.ts b/server/src/controllers/group.controller.ts
index 5bc30fe..99ac368 100644
--- a/server/src/controllers/group.controller.ts
+++ b/server/src/controllers/group.controller.ts
@@ -3,27 +3,37 @@ import {CreateGroupInput, GetGroupInput, getGroupSchema} from "../schemas/group.
import config from 'config';
import {Group} from "../entities/group.entity";
import AppError from "../errors/appError";
+import {randomBytes} from "crypto";
import {AppDataSource} from "../db/data-source";
+import {hashed_token} from "../auth";
+
const groupRepository = AppDataSource.getRepository(Group)
export const createGroupHandler = async(
req: Request<{}, {}, CreateGroupInput>,
res: Response
) => {
- console.log(req.body);
- const admin_token = config.get('admin_token');
- if (req.body.token !== admin_token){
- return res.status(403).json({
- status: 'fail',
- message: 'Not authorized to create group without correct admin token'
- })
- }
+ // console.log(req.body);
+ // const admin_token = config.get('admin_token');
+ // if (req.body?.token !== admin_token && req.session.hashed_token !== hashed_token){
+ // return res.status(403).json({
+ // status: 'fail',
+ // message: 'Not authorized to create group without correct admin token'
+ // })
+ // }
- let group = await groupRepository.create({...req.body})
+ // Make new invite token as a random UUID
+ // let invite_token = randomUUID();
+ // doesn't need to be as long as that...
+ let invite_token = randomBytes(8).toString('hex');
+
+ let group = await groupRepository.create({...req.body, invite_token})
let result = await groupRepository.save(group)
- return res.send(result)
+ console.log("Group successfully created")
+ console.log(result)
+ return res.send({"status": "success", "data": result})
}
@@ -33,20 +43,39 @@ export const getGroupHandler = async(
next: NextFunction
) => {
try {
- let group = await groupRepository.findOneBy({name: req.params.name})
- if (!group) {
- return next(new AppError(404, "No group with matching name exists"))
+ let query = req.body.name ?? req.query.name ?? undefined
+ let group;
+ if (query){
+ group = await groupRepository.findBy({name: query})
+ } else {
+ group = await groupRepository.find()
}
+ console.log(group);
+ if (group.length === 0) {
+ return res.status(404).json({
+ status: 'failed',
+ message: `No group with matching name exists. given name: ${query}`
+ })
+ }
+
+ console.log("Groups retrieved", group);
return res.status(200).json({
status: 'success',
- data: {
- group
- }
+ data: [
+ ...group
+ ]
})
} catch (err: any) {
next(err);
}
-};
\ No newline at end of file
+};
+
+export const getGroupsHandler = async(
+ req: Request,
+ res: Response
+) => {
+
+}
\ No newline at end of file
diff --git a/server/src/db/data-source.ts b/server/src/db/data-source.ts
index 3d56e21..340eca0 100644
--- a/server/src/db/data-source.ts
+++ b/server/src/db/data-source.ts
@@ -16,7 +16,8 @@ export const AppDataSource = new DataSource({
type: 'postgres',
synchronize: true,
logging: false,
- entities: ['server/entities/**/*.entity{.ts,.js}'],
- migrations: ['server/migrations/**/*{.ts,.js}'],
+ // dropSchema: true,
+ entities: ['src/entities/**/*.entity{.ts,.js}'],
+ // migrations: ['src/migrations/**/*{.ts,.js}'],
// subscribers: ['server/subscribers/**/*{.ts,.js}'],
});
diff --git a/server/src/entities/group.entity.ts b/server/src/entities/group.entity.ts
index efaf032..32c4304 100644
--- a/server/src/entities/group.entity.ts
+++ b/server/src/entities/group.entity.ts
@@ -14,6 +14,9 @@ export class Group extends Model {
})
enable: boolean;
+ @Column()
+ invite_token: string;
+
@OneToMany(() => Channel, (channel) => channel.bridge)
channels: Channel[]
diff --git a/server/src/index.d.ts b/server/src/index.d.ts
new file mode 100644
index 0000000..aeda724
--- /dev/null
+++ b/server/src/index.d.ts
@@ -0,0 +1,7 @@
+declare global {
+ namespace Express {
+ interface Session {
+ logged_in?: boolean
+ }
+ }
+}
\ No newline at end of file
diff --git a/server/src/middleware/cookies.ts b/server/src/middleware/cookies.ts
new file mode 100644
index 0000000..f4d67b4
--- /dev/null
+++ b/server/src/middleware/cookies.ts
@@ -0,0 +1,35 @@
+import cookieSession from 'cookie-session';
+import config from 'config';
+import {Request, Response, NextFunction} from "express";
+import { tokenHasher, hashed_token } from "../auth";
+
+const cookieConfig = config.get<{
+ 'key1': string,
+ "key2": string
+}>('cookies')
+
+
+
+export const cookieMiddleware = cookieSession({
+ name: 'session',
+ keys: [cookieConfig.key1, cookieConfig.key2],
+ signed: true,
+
+})
+
+export const requireAdmin = (req: Request, res: Response, next: NextFunction) => {
+ if (req.session.hashed_token === hashed_token){
+ next();
+ } else {
+ let token_input = req.params.token ?? req.body.token ?? req.query.token
+ let hashed_user_token = tokenHasher(token_input);
+ if (hashed_user_token === hashed_token) {
+ next();
+ } else{
+ return res.status(403).json({
+ status: 'fail',
+ message: 'this action requires you to be logged in as an administrator'
+ });
+ }
+ }
+};
diff --git a/server/src/routes/auth.routes.ts b/server/src/routes/auth.routes.ts
new file mode 100644
index 0000000..ca31080
--- /dev/null
+++ b/server/src/routes/auth.routes.ts
@@ -0,0 +1,13 @@
+import express from 'express';
+
+import {
+ checkAdminToken
+} from "../controllers/auth.controller";
+
+const router = express.Router();
+
+router
+ .route('/')
+ .post(checkAdminToken)
+
+export default router
diff --git a/server/src/routes/group.routes.ts b/server/src/routes/group.routes.ts
index 9c77e33..0b03476 100644
--- a/server/src/routes/group.routes.ts
+++ b/server/src/routes/group.routes.ts
@@ -10,12 +10,13 @@ import {
} from "../schemas/group.schema";
import { validate } from "../middleware/validate";
+import { requireAdmin } from "../middleware/cookies";
const router = express.Router();
router
.route('/')
- .post(createGroupHandler)
- .get(getGroupHandler)
+ .post(validate(createGroupSchema), requireAdmin, createGroupHandler)
+ .get(requireAdmin, getGroupHandler)
export default router
diff --git a/server/src/schemas/auth.schema.ts b/server/src/schemas/auth.schema.ts
new file mode 100644
index 0000000..0b01e6f
--- /dev/null
+++ b/server/src/schemas/auth.schema.ts
@@ -0,0 +1,13 @@
+import { object, string, TypeOf } from 'zod';
+
+export const checkAdminSchema = object({
+ body: object({
+ token: string({
+ required_error: "Administration token required to log in!"
+ })
+ })
+})
+
+
+
+export type CheckAdminInput = TypeOf['body'];
\ No newline at end of file
diff --git a/server/src/schemas/group.schema.ts b/server/src/schemas/group.schema.ts
index 5f59b1b..2384738 100644
--- a/server/src/schemas/group.schema.ts
+++ b/server/src/schemas/group.schema.ts
@@ -5,9 +5,9 @@ export const createGroupSchema = object({
name: string({
required_error: "Name for group required"
}),
- token: string({
- required_error: "Administration token required for creating groups"
- })
+ // token: string({
+ // required_error: "Administration token required for creating groups"
+ // })
})
})
diff --git a/server/tsconfig.json b/server/tsconfig.json
index 158a58a..774daf9 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -8,12 +8,13 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"strictPropertyInitialization": false,
+ "strictNullChecks": false,
"skipLibCheck": true,
"outDir": "./build",
"rootDir": ".",
},
- "include": ["server/**/*"],
+ "include": ["src/**/*"],
"exclude": [
"../node_modules", "roles"]
}
diff --git a/yarn.lock b/yarn.lock
index eab8fac..75eb701 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -168,7 +168,7 @@
dependencies:
"@babel/types" "^7.22.5"
-"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.22.5":
+"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c"
integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==
@@ -1110,7 +1110,7 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.8.4":
+"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.22.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
version "7.22.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438"
integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==
@@ -1279,6 +1279,113 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
+"@emotion/babel-plugin@^11.11.0":
+ version "11.11.0"
+ resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c"
+ integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.16.7"
+ "@babel/runtime" "^7.18.3"
+ "@emotion/hash" "^0.9.1"
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/serialize" "^1.1.2"
+ babel-plugin-macros "^3.1.0"
+ convert-source-map "^1.5.0"
+ escape-string-regexp "^4.0.0"
+ find-root "^1.1.0"
+ source-map "^0.5.7"
+ stylis "4.2.0"
+
+"@emotion/cache@^11.11.0":
+ version "11.11.0"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff"
+ integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
+ dependencies:
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/sheet" "^1.2.2"
+ "@emotion/utils" "^1.2.1"
+ "@emotion/weak-memoize" "^0.3.1"
+ stylis "4.2.0"
+
+"@emotion/hash@^0.9.1":
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
+ integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
+
+"@emotion/is-prop-valid@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc"
+ integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==
+ dependencies:
+ "@emotion/memoize" "^0.8.1"
+
+"@emotion/memoize@^0.8.1":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
+ integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
+
+"@emotion/react@^11.11.1":
+ version "11.11.1"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157"
+ integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
+ dependencies:
+ "@babel/runtime" "^7.18.3"
+ "@emotion/babel-plugin" "^11.11.0"
+ "@emotion/cache" "^11.11.0"
+ "@emotion/serialize" "^1.1.2"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
+ "@emotion/utils" "^1.2.1"
+ "@emotion/weak-memoize" "^0.3.1"
+ hoist-non-react-statics "^3.3.1"
+
+"@emotion/serialize@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51"
+ integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==
+ dependencies:
+ "@emotion/hash" "^0.9.1"
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/unitless" "^0.8.1"
+ "@emotion/utils" "^1.2.1"
+ csstype "^3.0.2"
+
+"@emotion/sheet@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec"
+ integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
+
+"@emotion/styled@^11.11.0":
+ version "11.11.0"
+ resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346"
+ integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==
+ dependencies:
+ "@babel/runtime" "^7.18.3"
+ "@emotion/babel-plugin" "^11.11.0"
+ "@emotion/is-prop-valid" "^1.2.1"
+ "@emotion/serialize" "^1.1.2"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
+ "@emotion/utils" "^1.2.1"
+
+"@emotion/unitless@^0.8.1":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
+ integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
+
+"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
+ integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
+
+"@emotion/utils@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4"
+ integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
+
+"@emotion/weak-memoize@^0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
+ integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
+
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -1619,6 +1726,92 @@
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
+"@mui/base@5.0.0-beta.8", "@mui/base@^5.0.0-beta.8":
+ version "5.0.0-beta.8"
+ resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.8.tgz#a0a9531ae9147be92d17e4f0e3b9accc57916841"
+ integrity sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==
+ dependencies:
+ "@babel/runtime" "^7.22.6"
+ "@emotion/is-prop-valid" "^1.2.1"
+ "@mui/types" "^7.2.4"
+ "@mui/utils" "^5.14.1"
+ "@popperjs/core" "^2.11.8"
+ clsx "^1.2.1"
+ prop-types "^15.8.1"
+ react-is "^18.2.0"
+
+"@mui/core-downloads-tracker@^5.14.2":
+ version "5.14.2"
+ resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.2.tgz#d8fcacdb1d37e621fce33ea808180fa5a590f908"
+ integrity sha512-x+c/MgDL1t/IIy5lDbMlrDouFG5DYZbl3DP4dbbuhlpPFBnE9glYwmJEee/orVHQpOPwLxCAIWQs+2DKSaBVWQ==
+
+"@mui/material@^5.14.2":
+ version "5.14.2"
+ resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.2.tgz#13b113489a61021145d62e0383912ca487a46375"
+ integrity sha512-TgNR4/YRL11RifsnMWNhITNCkGJYVz20SCvVJBBoU5Y/KhUNSSJxjDpEB8VrnY+sUsV0NigLCkHZJglfsiS3Pw==
+ dependencies:
+ "@babel/runtime" "^7.22.6"
+ "@mui/base" "5.0.0-beta.8"
+ "@mui/core-downloads-tracker" "^5.14.2"
+ "@mui/system" "^5.14.1"
+ "@mui/types" "^7.2.4"
+ "@mui/utils" "^5.14.1"
+ "@types/react-transition-group" "^4.4.6"
+ clsx "^1.2.1"
+ csstype "^3.1.2"
+ prop-types "^15.8.1"
+ react-is "^18.2.0"
+ react-transition-group "^4.4.5"
+
+"@mui/private-theming@^5.13.7":
+ version "5.13.7"
+ resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.13.7.tgz#2f8ef5da066f3c6c6423bd4260d003a28d10b099"
+ integrity sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+ "@mui/utils" "^5.13.7"
+ prop-types "^15.8.1"
+
+"@mui/styled-engine@^5.13.2":
+ version "5.13.2"
+ resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.13.2.tgz#c87bd61c0ab8086d34828b6defe97c02bcd642ef"
+ integrity sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==
+ dependencies:
+ "@babel/runtime" "^7.21.0"
+ "@emotion/cache" "^11.11.0"
+ csstype "^3.1.2"
+ prop-types "^15.8.1"
+
+"@mui/system@^5.14.1":
+ version "5.14.1"
+ resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.1.tgz#ec8ae69f63963b5916dad4bca2f8a86a001a2392"
+ integrity sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==
+ dependencies:
+ "@babel/runtime" "^7.22.6"
+ "@mui/private-theming" "^5.13.7"
+ "@mui/styled-engine" "^5.13.2"
+ "@mui/types" "^7.2.4"
+ "@mui/utils" "^5.14.1"
+ clsx "^1.2.1"
+ csstype "^3.1.2"
+ prop-types "^15.8.1"
+
+"@mui/types@^7.2.4":
+ version "7.2.4"
+ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.4.tgz#b6fade19323b754c5c6de679a38f068fd50b9328"
+ integrity sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==
+
+"@mui/utils@^5.13.7", "@mui/utils@^5.14.1":
+ version "5.14.1"
+ resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.1.tgz#29696371016552a6eb3af975bc7af429ec88b29a"
+ integrity sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==
+ dependencies:
+ "@babel/runtime" "^7.22.6"
+ "@types/prop-types" "^15.7.5"
+ "@types/react-is" "^18.2.1"
+ prop-types "^15.8.1"
+ react-is "^18.2.0"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
@@ -1662,6 +1855,11 @@
schema-utils "^3.0.0"
source-map "^0.7.3"
+"@popperjs/core@^2.11.8":
+ version "2.11.8"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
+ integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
+
"@redis/bloom@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.2.0.tgz#d3fd6d3c0af3ef92f26767b56414a370c7b63b71"
@@ -2014,6 +2212,14 @@
dependencies:
"@types/node" "*"
+"@types/cookie-session@^2.0.44":
+ version "2.0.44"
+ resolved "https://registry.yarnpkg.com/@types/cookie-session/-/cookie-session-2.0.44.tgz#86f3810bf19716ff716e08f877ce40cee9062267"
+ integrity sha512-3DheOZ41pql6raSIkqEPphJdhA2dX2bkS+s2Qacv8YMKkoCbAIEXbsDil7351ARzMqvfyDUGNeHGiRZveIzhqQ==
+ dependencies:
+ "@types/express" "*"
+ "@types/keygrip" "*"
+
"@types/cors@^2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94"
@@ -2141,6 +2347,11 @@
dependencies:
"@types/node" "*"
+"@types/keygrip@*":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72"
+ integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==
+
"@types/mime@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
@@ -2171,7 +2382,7 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f"
integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
-"@types/prop-types@*":
+"@types/prop-types@*", "@types/prop-types@^15.7.5":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
@@ -2203,6 +2414,20 @@
dependencies:
"@types/react" "*"
+"@types/react-is@^18.2.1":
+ version "18.2.1"
+ resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.1.tgz#61d01c2a6fc089a53520c0b66996d458fdc46863"
+ integrity sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react-transition-group@^4.4.6":
+ version "4.4.6"
+ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e"
+ integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==
+ dependencies:
+ "@types/react" "*"
+
"@types/react@*", "@types/react@^18.2.16":
version "18.2.16"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.16.tgz#403dda0e933caccac9efde569923239ac426786c"
@@ -3294,7 +3519,7 @@ check-types@^11.1.1:
resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4"
integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==
-chokidar@^3.4.2, chokidar@^3.5.1, chokidar@^3.5.3:
+"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.1, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -3370,6 +3595,11 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
+clsx@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
+ integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
+
cluster-key-slot@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
@@ -3552,11 +3782,21 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
-convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
+convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
+cookie-session@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/cookie-session/-/cookie-session-2.0.0.tgz#d07aa27822f43619e4342df1342268c849833089"
+ integrity sha512-hKvgoThbw00zQOleSlUr2qpvuNweoqBtxrmx0UFosx6AGi9lYtLoA+RbsvknrEX8Pr6MDbdWAb2j6SnMn+lPsg==
+ dependencies:
+ cookies "0.8.0"
+ debug "3.2.7"
+ on-headers "~1.0.2"
+ safe-buffer "5.2.1"
+
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@@ -3567,6 +3807,14 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+cookies@0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90"
+ integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==
+ dependencies:
+ depd "~2.0.0"
+ keygrip "~1.1.0"
+
core-js-compat@^3.31.0:
version "3.31.1"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0"
@@ -3668,7 +3916,7 @@ css-has-pseudo@^3.0.4:
dependencies:
postcss-selector-parser "^6.0.9"
-css-loader@^6.5.1:
+css-loader@^6.5.1, css-loader@^6.8.1:
version "6.8.1"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88"
integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==
@@ -3834,7 +4082,7 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"
-csstype@^3.0.2:
+csstype@^3.0.2, csstype@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
@@ -3867,6 +4115,13 @@ debug@2.6.9, debug@^2.6.0:
dependencies:
ms "2.0.0"
+debug@3.2.7, debug@^3.2.7:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+ dependencies:
+ ms "^2.1.1"
+
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@@ -3874,13 +4129,6 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
dependencies:
ms "2.1.2"
-debug@^3.2.7:
- version "3.2.7"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
- integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
- dependencies:
- ms "^2.1.1"
-
decimal.js@^10.2.1:
version "10.4.3"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
@@ -3926,7 +4174,7 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
-depd@2.0.0:
+depd@2.0.0, depd@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
@@ -4029,6 +4277,14 @@ dom-converter@^0.2.0:
dependencies:
utila "~0.4"
+dom-helpers@^5.0.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
+ integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
+ dependencies:
+ "@babel/runtime" "^7.8.7"
+ csstype "^3.0.2"
+
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -4779,6 +5035,11 @@ find-cache-dir@^3.3.1:
make-dir "^3.0.2"
pkg-dir "^4.1.0"
+find-root@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
+ integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
+
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
@@ -5186,6 +5447,13 @@ highlight.js@^10.7.1:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
+hoist-non-react-statics@^3.3.1:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
hoopy@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
@@ -5376,6 +5644,11 @@ immer@^9.0.7:
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176"
integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
+immutable@^4.0.0:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.1.tgz#17988b356097ab0719e2f741d56f3ec6c317f9dc"
+ integrity sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==
+
import-fresh@^3.1.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@@ -6396,6 +6669,13 @@ jws@^3.2.2:
jwa "^1.4.1"
safe-buffer "^5.0.1"
+keygrip@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
+ integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==
+ dependencies:
+ tsscmp "1.0.6"
+
kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
@@ -7938,7 +8218,7 @@ prompts@^2.0.1, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.8.1:
+prop-types@^15.6.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -8174,7 +8454,7 @@ react-error-overlay@^6.0.11:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
-react-is@^16.13.1:
+react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -8184,7 +8464,7 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-react-is@^18.0.0:
+react-is@^18.0.0, react-is@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
@@ -8249,6 +8529,16 @@ react-scripts@5.0.1:
optionalDependencies:
fsevents "^2.3.2"
+react-transition-group@^4.4.5:
+ version "4.4.5"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
+ integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ dom-helpers "^5.0.1"
+ loose-envify "^1.4.0"
+ prop-types "^15.6.2"
+
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@@ -8573,6 +8863,22 @@ sass-loader@^12.3.0:
klona "^2.0.4"
neo-async "^2.6.2"
+sass-loader@^13.3.2:
+ version "13.3.2"
+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.3.2.tgz#460022de27aec772480f03de17f5ba88fa7e18c6"
+ integrity sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==
+ dependencies:
+ neo-async "^2.6.2"
+
+sass@^1.64.1:
+ version "1.64.1"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.64.1.tgz#6a46f6d68e0fa5ad90aa59ce025673ddaa8441cf"
+ integrity sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
sax@~1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -8811,7 +9117,7 @@ source-list-map@^2.0.0, source-list-map@^2.0.1:
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
-source-map-js@^1.0.1, source-map-js@^1.0.2:
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
@@ -8838,6 +9144,11 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+source-map@^0.5.7:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+ integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
+
source-map@^0.7.3:
version "0.7.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
@@ -9093,7 +9404,7 @@ strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
-style-loader@^3.3.1:
+style-loader@^3.3.1, style-loader@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff"
integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==
@@ -9106,6 +9417,11 @@ stylehacks@^5.1.1:
browserslist "^4.21.4"
postcss-selector-parser "^6.0.4"
+stylis@4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51"
+ integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
+
sucrase@^3.32.0:
version "3.34.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f"
@@ -9456,6 +9772,11 @@ tslib@^2.0.3, tslib@^2.1.0, tslib@^2.5.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410"
integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==
+tsscmp@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
+ integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
+
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"