use ESM, add server setup, cleanup
Change-Id: Iafac35c2082523ae98c31017d9bad5c4d6e18ef3
diff --git a/JamiDaemon.js b/JamiDaemon.js
index 404915b..841b979 100755
--- a/JamiDaemon.js
+++ b/JamiDaemon.js
@@ -17,10 +17,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-"use strict";
+"use strict"
-const Account = require('./model/Account')
-const Conversation = require('./model/Conversation')
+import Account from './model/Account.js'
+import Conversation from './model/Conversation.js'
+import { createRequire } from 'module';
+const require = createRequire(import.meta.url);
class JamiDaemon {
constructor() {
@@ -66,13 +68,13 @@
console.log(`Received message: ${accountId} ${from} ${message["text/plain"]}`)
/*
if (parser.validate(message["text/plain"]) === true) {
- console.log(message["text/plain"]);
+ console.log(message["text/plain"])
} else {
- user = connectedUsers[accountId];
+ user = connectedUsers[accountId]
console.log(user.socketId)
- io.to(user.socketId).emit('receivedMessage', message["text/plain"]);
- //io.emit('receivedMessage', message["text/plain"]);
+ io.to(user.socketId).emit('receivedMessage', message["text/plain"])
+ //io.emit('receivedMessage', message["text/plain"])
}*/
},
"RegistrationStateChanged": (accountId, state, /*int*/ code, detail) => {
@@ -109,14 +111,14 @@
const contact = account.getContactFromCache(address)
contact.setRegisteredName(name)
}
- let index = account.lookups.length - 1;
+ let index = account.lookups.length - 1
while (index >= 0) {
const lookup = account.lookups[index]
if ((lookup.address && lookup.address === address) || (lookup.name && lookup.name === name)) {
lookup.resolve({address, name, state})
- account.lookups.splice(index, 1);
+ account.lookups.splice(index, 1)
}
- index -= 1;
+ index -= 1
}
},
"ConversationReady": (accountId, conversationId) => {
@@ -303,7 +305,7 @@
params.set("Account.archivePassword", account.archivePassword)
} else {
console.log("archivePassword required")
- return;
+ return
}
if (account.alias)
params.set("Account.alias", account.alias)
@@ -371,8 +373,8 @@
mapToNative(map){
const ret = new this.dring.StringMap()
map.forEach((value, key) => ret.set(key, value))
- return ret;
+ return ret
}
}
-module.exports = JamiDaemon;
+export default JamiDaemon
diff --git a/app.js b/app.js
index 0c92661..ef03a00 100644
--- a/app.js
+++ b/app.js
@@ -1,46 +1,63 @@
-require('dotenv').config()
+'use strict'
-const express = require('express')
-const http = require('http')
-const session = require('express-session')
+import dotenv from 'dotenv'
+dotenv.config()
+
+import { promises as fs } from 'fs'
+import http from 'http'
+import express from 'express'
+import session from 'express-session'
//const cookieParser = require('cookie-parser')
//const io = require('socket.io')(server)
-const path = require('path')
-const passport = require('passport')
- , LocalStrategy = require('passport-local').Strategy
+import path from 'path'
+import passport from 'passport'
+import { Strategy as LocalStrategy } from 'passport-local'
+//import { createRequire } from 'module';
+//const require = createRequire(import.meta.url);
+import { fileURLToPath } from 'url';
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
//const redis = require('redis-url').connect()
//const RedisStore = require('connect-redis')(session)
/*const passportSocketIo = require('passport.socketio')*/
-const indexRouter = require('./routes/index')
+import indexRouter from './routes/index.js'
//const cors = require('cors')
-const JamiRestApi = require('./routes/jami')
-const JamiDaemon = require('./JamiDaemon')
+import JamiRestApi from './routes/jami.js'
+import JamiDaemon from './JamiDaemon.js'
+
+const configPath = 'jamiServerConfig.json'
//const sessionStore = new RedisStore({ client: redis })
const sessionStore = new session.MemoryStore()
const loadConfig = async (filePath) => {
+ const config = {users: {}, authMethods: []}
try {
- return JSON.parse(await fs.readFile(filePath))
- } catch {
- return {}
+ return Object.assign(config, JSON.parse(await fs.readFile(filePath)))
+ } catch(e) {
+ console.log(e)
+ return config
}
}
+const saveConfig = (filePath, config) => {
+ return fs.writeFile(filePath, JSON.stringify(config))
+}
+
/*
Share sessions between Passport.js and Socket.io
*/
function logSuccess() {
- console.log("passportSocketIo authorized user with Success 😁");
+ console.log("passportSocketIo authorized user with Success 😁")
}
function logFail() {
- console.log("passportSocketIo failed to authorized user 👺");
+ console.log("passportSocketIo failed to authorized user 👺")
}
/*
@@ -52,8 +69,8 @@
web socket call
*/
-const tempAccounts = {};
-const connectedUsers = {};
+const tempAccounts = {}
+const connectedUsers = {}
const createServer = async (appConfig) => {
const app = express()
@@ -62,19 +79,23 @@
const development = app.get('env') === 'development'
if (development) {
- const webpack = require('webpack')
- const webpackConfig = require('./client/webpack.config.js')
- const compiler = webpack(webpackConfig)
- app.use(require('webpack-dev-middleware')(compiler, {
- publicPath: webpackConfig.output.publicPath
- }));
- app.use(require('webpack-hot-middleware')(compiler));
+ const [ webpack, webpackDev, webpackHot, webpackConfig ] = await Promise.all([
+ import('webpack'),
+ import('webpack-dev-middleware'),
+ import('webpack-hot-middleware'),
+ import('./client/webpack.config.js')
+ ])
+ const compiler = webpack.default(webpackConfig.default)
+ app.use(webpackDev.default(compiler, {
+ publicPath: webpackConfig.default.output.publicPath
+ }))
+ app.use(webpackHot.default(compiler))
}
/*
Configuation for Passeport Js
*/
- app.disable('x-powered-by');
+ app.disable('x-powered-by')
app.use(session({
store: sessionStore,
@@ -85,13 +106,13 @@
maxAge: 2419200000
},
secret: process.env.SECRET_KEY_BASE
- }));
- app.use(passport.initialize());
- app.use(passport.session());
- // app.use(app.router);
+ }))
+ app.use(passport.initialize())
+ app.use(passport.session())
+ // app.use(app.router)
//app.use(cors())
- const jami = new JamiDaemon();
+ const jami = new JamiDaemon()
const apiRouter = new JamiRestApi(jami).getRouter()
/*
@@ -103,166 +124,204 @@
cookieParser: cookieParser,
//success: logSuccess(),
// fail: logFail(),
- }));
+ }))
*/
+ const isSetupComplete = () => {
+ return 'admin' in appConfig.users
+ }
+
+ const accountFilter = filter => {
+ if (typeof filter === 'string') {
+ if (filter === '*')
+ return undefined
+ else
+ return account => account.getId() === filter
+ } else if (Array.isArray(filter)) {
+ return account => filter.includes(account.getId())
+ } else {
+ throw new Error('Invalid account filter string')
+ }
+ }
+
+ const user = (id, config) => {
+ return {
+ id,
+ config,
+ username: config.username || id,
+ accountFilter: accountFilter(config.accounts)
+ }
+ }
+
passport.serializeUser((user, done) => {
+ connectedUsers[user.id] = user.config
+ console.log("=============================SerializeUser called " + user.id)
console.log(user)
- connectedUsers[user.accountId] = user;
- console.log("=============================SerializeUser called " + user.accountId)
- done(null, user.accountId);
- });
+ done(null, user.id)
+ })
const deserializeUser = (id, done) => {
- console.log("=============================DeserializeUser called on: " + id + " " + connectedUsers[id])
- done(null, connectedUsers[id]);
- };
- passport.deserializeUser(deserializeUser);
-
- //var tempAccountId = '';
+ console.log("=============================DeserializeUser called on: " + id)
+ const userConfig = connectedUsers[id]
+ console.log(userConfig)
+ if (userConfig) {
+ done(null, user(id, userConfig))
+ } else
+ done(404, null)
+ }
+ passport.deserializeUser(deserializeUser)
const jamsStrategy = new LocalStrategy(
(username, password, done) => {
-
- const newUser = {};
- newUser.username = username;
- //newUser.socketid =
-
const accountId = jami.addAccount({
'managerUri': 'https://jams.savoirfairelinux.com',
'managerUsername': username,
'archivePassword': password
- });
+ })
+ const id = `jams_${username}`
+ const userConfig = { username, type: 'jams', accounts: accountId }
+ const newUser = user(id, userConfig)
+ console.log("AccountId: " + accountId)
+ tempAccounts[accountId] = { done, newUser }
- const newProps = jami.getAccount(accountId).details;
- console.log(newProps);
- //Object.entries(newProps).forEach(v => console.log(v[0], v[1]))
- //tempAccountId = accountId;
- newUser.accountId = accountId;
- console.log("AccountId: " + accountId);
- connectedUsers[accountId] = newUser;
- tempAccounts[accountId] = { done, newUser };
-
- //return done(null, newUser);
-
- /*User.findOne({ username: username }, function (err, user) {
- if (err) { return done(err); }
- if (!user) {
- return done(null, false, { message: 'Incorrect username.' });
- }
- if (!user.validPassword(password)) {
- return done(null, false, { message: 'Incorrect password.' });
- }
- return done(null, user);
- });*/
}
- );
- jamsStrategy.name = "jams";
+ )
+ jamsStrategy.name = "jams"
const localStrategy = new LocalStrategy(
(username, password, done) => {
- console.log("localStrategy: " + username + " " + password);
+ console.log("localStrategy: " + username + " " + password)
- const newUser = {};
- newUser.accountId = jami.getAccountList()[0].getId();
- console.log("Local AccountId: " + newUser.accountId);
- connectedUsers[newUser.accountId] = newUser;
- done(null, newUser);
+ const id = username
+ const userConfig = appConfig.users[username]
+ if (!userConfig) {
+ return done(null, false, { message: 'Incorrect username.' })
+ }
+ if (userConfig.password !== password) {
+ return done(null, false, { message: 'Incorrect password.' })
+ }
+ userConfig.type = 'local'
+
+ done(null, user(id, userConfig))
}
- );
+ )
- passport.use(jamsStrategy);
- passport.use(localStrategy);
+ passport.use(jamsStrategy)
+ passport.use(localStrategy)
const secured = (req, res, next) => {
- console.log(`isSecured ${req.user}`);
- if (req.user && req.user.accountId) {
- return next();
+ if (req.user) {
+ return next()
}
res.status(401).end()
- };
+ }
const securedRedirect = (req, res, next) => {
if (req.user && req.user.accountId) {
- return next();
+ return next()
}
- req.session.returnTo = req.originalUrl;
- res.redirect('/login');
- };
+ req.session.returnTo = req.originalUrl
+ res.redirect('/login')
+ }
- app.post('/auth', passport.authenticate('jams'), (req, res) => {
+ app.use(express.json())
+ app.post('/setup', (req, res) => {
+ if (isSetupComplete()) {
+ return res.status(404).end()
+ }
+ if (!req.body.password) {
+ return res.status(400).end()
+ }
+ console.log(req.body)
+ appConfig.users.admin = {
+ "accounts": "*",
+ password: req.body.password
+ }
+ res.status(200).end()
+ saveConfig(configPath, appConfig)
+ })
+ app.post('/auth/jams', passport.authenticate('jams'), (req, res) => {
res.json({ loggedin: true })
- });
- app.post('auth/localLogin', passport.authenticate('local'), (req, res) => {
- res.json({ loggedin: true })
- });
+ })
+ app.post('/auth/local', passport.authenticate('local'), (req, res) => {
+ res.json({ loggedin: true, user: req.user.id })
+ })
+ app.get('/auth', (req, res) => {
+ if (req.user) {
+ res.json({ loggedin: true, username: req.user.username, type: req.user.type })
+ } else if (isSetupComplete()) {
+ res.status(401).json({})
+ } else {
+ res.status(401).json({ setupComplete: false })
+ }
+ })
- app.use('/api', secured, apiRouter);
+ app.use('/api', secured, apiRouter)
- app.use('/', indexRouter);
+ app.use('/', indexRouter)
/* GET React App */
app.use(express.static(path.join(__dirname, 'client', 'dist')))
app.use((req, res, next) => {
- res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'));
- });
+ res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'))
+ })
- return http.Server(app);
+ return http.Server(app)
}
-loadConfig()
+loadConfig(configPath)
.then(createServer)
.then(server => {
- server.listen(3000);
+ server.listen(3000)
})
/*
io.on('connection', (socket) => {
console.log("Client just connected !")
socket.on('SendMessage', (data) => {
- console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId);
- const msgMap = new jami.dring.StringMap();
- msgMap.set('text/plain', data.text);
- jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap);
- });
-});
+ console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId)
+ const msgMap = new jami.dring.StringMap()
+ msgMap.set('text/plain', data.text)
+ jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap)
+ })
+})
io.use((socket, next) => {
cookieParser(socket.handshake, {}, (err) => {
if (err) {
- console.log("error in parsing cookie");
- return next(err);
+ console.log("error in parsing cookie")
+ return next(err)
}
if (!socket.handshake.signedCookies) {
- console.log("no secureCookies|signedCookies found");
- return next(new Error("no secureCookies found"));
+ console.log("no secureCookies|signedCookies found")
+ return next(new Error("no secureCookies found"))
}
sessionStore.get(socket.handshake.signedCookies["connect.sid"], (err, session) => {
- socket.session = session;
- if (!err && !session) err = new Error('session not found');
+ socket.session = session
+ if (!err && !session) err = new Error('session not found')
if (err) {
- console.log('failed connection to socket.io:', err);
+ console.log('failed connection to socket.io:', err)
} else {
- console.log(session);
- console.log('successful connection to socket.io ' + session.passport.user);
- const userKey = session.passport.user;
+ console.log(session)
+ console.log('successful connection to socket.io ' + session.passport.user)
+ const userKey = session.passport.user
deserializeUser(userKey, (err, user) => {
console.log("deserializeUser: " + user)
if (err)
- return next(err, true);
+ return next(err, true)
if (!user)
- return next("User not found", false);
+ return next("User not found", false)
console.log("User associated socket id: " + socket.id)
- user.socketId = socket.id;
- socket.session.user = user;
- console.log("User added to session --------> " + user.accountId);
- //auth.success(data, accept);
- next(err, true);
- });
+ user.socketId = socket.id
+ socket.session.user = user
+ console.log("User added to session --------> " + user.accountId)
+ //auth.success(data, accept)
+ next(err, true)
+ })
}
- });
- });
-});
+ })
+ })
+})
*/
diff --git a/client/package.json b/client/package.json
index 56ad635..6cd7d4d 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,11 +1,13 @@
{
"name": "jami-web-client",
+ "type": "module",
"version": "0.1.0",
"private": true,
"dependencies": {
- "@material-ui/core": "^4.10.2",
- "@material-ui/icons": "^4.9.1",
- "@material-ui/lab": "^4.0.0-alpha.56",
+ "@babel/runtime": "^7.13.10",
+ "@material-ui/core": "^4.11.3",
+ "@material-ui/icons": "^4.11.2",
+ "@material-ui/lab": "^4.0.0-alpha.57",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
@@ -18,12 +20,15 @@
"socket.io-client": "^2.3.0"
},
"devDependencies": {
+ "@babel/plugin-transform-runtime": "^7.13.15",
"@babel/core": "^7.13.14",
"@babel/preset-env": "^7.13.12",
"@babel/preset-react": "^7.13.13",
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.0-beta.3",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.0",
"html-webpack-plugin": "^5.3.1",
+ "react-refresh": "^0.10.0",
"sass": "^1.32.8",
"sass-loader": "^11.0.1",
"style-loader": "^2.0.0",
diff --git a/client/src/App.js b/client/src/App.js
index 10db90a..cc1b5bf 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -3,52 +3,59 @@
Author: Larbi Gharib <larbi.gharib@savoirfairelinux.com>
License: AGPL-3
*/
-
-import React from 'react';
-import CssBaseline from '@material-ui/core/CssBaseline';
+import React, { useState, useEffect } from 'react'
+import { Route, Switch, Redirect, useHistory, useLocation } from 'react-router-dom'
+import { CircularProgress, Container, CssBaseline } from '@material-ui/core'
import authManager from './AuthManager'
-//import logo from './logo.svg';
-import './App.scss';
-
-import { BrowserRouter as Router, Route, Switch, Link, Redirect } from 'react-router-dom';
+//import logo from './logo.svg'
+import './App.scss'
import SignInPage from "./pages/loginDialog.jsx"
import JamiMessenger from "./pages/messenger.jsx"
import AccountSettings from "./pages/accountSettings.jsx"
import AccountSelection from "./pages/accountSelection.jsx"
-import AddContactPage from "./pages/addContactPage.jsx"
-
+import ServerSetup from "./pages/serverSetup.jsx"
import NotFoundPage from "./pages/404.jsx"
-class App extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- authenticated: authManager.isAuthenticated(),
- };
- authManager.setOnAuthChanged(authenticated => this.setState({authenticated}))
- }
+const App = (props) => {
+ const history = useHistory()
+ const { location } = useLocation()
+ const [state, setState] = useState({
+ loaded: false,
+ auth: authManager.getState()
+ })
+ useEffect(() => {
+ authManager.init(auth => {
+ setState({ loaded: true, auth })
+ })
+ return () => authManager.deinit()
+ }, []);
- render() {
console.log("App render")
- console.log(this.props)
+ console.log(state)
+ console.log(location)
- return <React.Fragment>
- <CssBaseline />
- <Router>
- <Switch>
- <Route exact path="/"><Redirect to="/account" /></Route>
- <Route path="/account/:accountId/settings" component={AccountSettings} />
- <Route path="/account/:accountId/addContact/:contactId" component={JamiMessenger} />
- <Route path="/account/:accountId/conversation/:conversationId" component={JamiMessenger} />
- <Route path="/account/:accountId" component={JamiMessenger} />
- <Route path="/account" component={AccountSelection} />
- <Route component={NotFoundPage} />
- </Switch>
- </Router>
- {!this.state.authenticated && <SignInPage open={!this.state.authenticated}/>}
- </React.Fragment>
- }
+ if (!state.loaded) {
+ return <Container><CircularProgress /></Container>
+ } else if (!state.auth.setupComplete) {
+ return <Switch>
+ <Route path="/setup" component={ServerSetup} />
+ <Route><Redirect to="/setup" /></Route>
+ </Switch>
+ }
+ return <React.Fragment>
+ <CssBaseline />
+ <Switch>
+ <Route exact path="/"><Redirect to="/account" /></Route>
+ <Route path="/account/:accountId/settings" component={AccountSettings} />
+ <Route path="/account/:accountId/addContact/:contactId" component={JamiMessenger} />
+ <Route path="/account/:accountId/conversation/:conversationId" component={JamiMessenger} />
+ <Route path="/account/:accountId" component={JamiMessenger} />
+ <Route path="/account" component={AccountSelection} />
+ <Route component={NotFoundPage} />
+ </Switch>
+ {!state.auth.authenticated && <SignInPage open={!state.auth.authenticated}/>}
+ </React.Fragment>
}
-export default App
\ No newline at end of file
+export default App
diff --git a/client/src/AuthManager.js b/client/src/AuthManager.js
index 09aef64..4f504db 100644
--- a/client/src/AuthManager.js
+++ b/client/src/AuthManager.js
@@ -17,39 +17,114 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-//import cookie from 'cookie';
-
class AuthManager {
constructor() {
console.log("AuthManager()")
- this.authenticated = true//'connect.sid' in cookie.parse(document.cookie)
this.authenticating = false
+
+ this.state = {
+ initialized: false,
+ authenticated: true,
+ setupComplete: true,
+ error: false
+ }
+
this.tasks = []
this.onAuthChanged = undefined
}
- setOnAuthChanged(onAuthChanged) {
- this.onAuthChanged = onAuthChanged
- }
isAuthenticated() {
- return this.authenticated
+ return this.state.authenticated
}
- authenticate() {
+ getState() {
+ return this.state
+ }
+
+ init(cb) {
+ this.onAuthChanged = cb
+ if (this.state.initialized || this.authenticating)
+ return
+ console.log("Init")
+ this.authenticating = true
+ fetch('/auth')
+ .then(async (response) => {
+ this.authenticating = false
+ this.state.initialized = true
+ console.log("Init ended")
+ console.log(response)
+ if (response.status === 200) {
+ const jsonData = await response.json()
+ Object.assign(this.state, {
+ authenticated: true,
+ setupComplete: true,
+ error: false,
+ user: { username: jsonData.username, type: jsonData.type }
+ })
+ } else if (response.status === 401) {
+ const jsonData = await response.json()
+ Object.assign(this.state, {
+ authenticated: false,
+ setupComplete: 'setupComplete' in jsonData ? jsonData.setupComplete : true,
+ error: false
+ })
+ } else {
+ this.state.error = true
+ }
+ console.log("New auth state")
+ console.log(this.state)
+
+ if (this.onAuthChanged)
+ this.onAuthChanged(this.state)
+ })
+ }
+
+ deinit() {
+ console.log("Deinit")
+ this.onAuthChanged = undefined
+ }
+
+ async setup(password) {
+ if (this.authenticating || this.state.setupComplete)
+ return
+ console.log("Starting setup")
+ this.authenticating = true
+ const response = await fetch(`/setup`, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ password })
+ })
+ console.log(response)
+ if (response.ok) {
+ console.log("Success, going home")
+ //history.replace('/')
+ } else {
+ }
+ this.authenticating = false
+ this.state.setupComplete = true
+ if (this.onAuthChanged)
+ this.onAuthChanged(this.state)
+ return response.ok
+ }
+
+ authenticate(username, password) {
if (this.authenticating)
return
console.log("Starting authentication")
this.authenticating = true
- fetch('/api/localLogin?username=local&password=local', { method:"POST" })
+ fetch(`/auth/local?username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`, { method:"POST" })
.then(response => {
console.log(response)
this.authenticating = false
- this.authenticated = response.ok && response.status === 200
+ this.state.authenticated = response.ok && response.status === 200
if (this.onAuthChanged)
- this.onAuthChanged(this.authenticated)
+ this.onAuthChanged(this.state)
while (this.tasks.length !== 0) {
const task = this.tasks.shift()
- if (this.authenticated)
+ if (this.state.authenticated)
fetch(task.url, task.init).then(res => task.resolve(res))
else
task.reject(new Error("Authentication failed"))
@@ -59,14 +134,14 @@
disconnect() {
console.log("Disconnect")
- this.authenticated = false
+ this.state.authenticated = false
if (this.onAuthChanged)
- this.onAuthChanged(this.authenticated)
+ this.onAuthChanged(this.state)
}
fetch(url, init) {
console.log(`get ${url}`)
- if (!this.authenticated) {
+ if (!this.state.authenticated) {
return new Promise((resolve, reject) => this.tasks.push({url, init, resolve, reject}))
}
return fetch(url, init)
diff --git a/client/src/components/AccountList.js b/client/src/components/AccountList.js
index 6f38c3c..38f1291 100644
--- a/client/src/components/AccountList.js
+++ b/client/src/components/AccountList.js
@@ -1,29 +1,19 @@
-import React from 'react';
+import React from 'react'
+import { Avatar, List, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core'
+import { PersonRounded } from '@material-ui/icons';
-import List from '@material-ui/core/List';
-import ListItem from '@material-ui/core/ListItem';
-import ListItemText from '@material-ui/core/ListItemText';
-import ListItemAvatar from '@material-ui/core/ListItemAvatar';
-import Avatar from '@material-ui/core/Avatar';
-import PersonRoundedIcon from '@material-ui/icons/PersonRounded';
-
-class AccountList extends React.Component {
- render() {
- return (
- <List>
- {
- this.props.accounts.map(account => <ListItem button key={account.getId()} onClick={() => this.props.onClick(account)}>
- <ListItemAvatar>
- <Avatar>
- <PersonRoundedIcon />
- </Avatar>
- </ListItemAvatar>
- <ListItemText primary={account.getDisplayName()} secondary={account.getDisplayUri()} />
- </ListItem>
- )
- }
- </List>)
- }
+export default function AccountList(props) {
+ return <List>
+ {
+ props.accounts.map(account => {
+ const displayName = account.getDisplayNameNoFallback()
+ return <ListItem button key={account.getId()} onClick={() => props.onClick(account)}>
+ <ListItemAvatar>
+ <Avatar>{displayName ? displayName[0].toUpperCase() : <PersonRounded />}</Avatar>
+ </ListItemAvatar>
+ <ListItemText primary={account.getDisplayName()} secondary={account.getDisplayUri()} />
+ </ListItem>
+ })
+ }
+ </List>
}
-
-export default AccountList;
\ No newline at end of file
diff --git a/client/src/components/ConversationListItem.js b/client/src/components/ConversationListItem.js
index 7e13974..a769168 100644
--- a/client/src/components/ConversationListItem.js
+++ b/client/src/components/ConversationListItem.js
@@ -2,7 +2,7 @@
import React from 'react'
import Conversation from '../../../model/Conversation'
import { useHistory, useParams } from "react-router-dom"
-import PersonIcon from '@material-ui/icons/PersonRounded'
+import { PersonRounded } from '@material-ui/icons'
export default function ConversationListItem(props) {
const { conversationId, contactId } = useParams()
@@ -22,7 +22,7 @@
style={{overflow:'hidden'}}
onClick={() => history.push(`/account/${conversation.getAccountId()}/${uri}`)}>
<ListItemAvatar>
- <Avatar>{displayName ? displayName[0].toUpperCase() : <PersonIcon />}</Avatar>
+ <Avatar>{displayName ? displayName[0].toUpperCase() : <PersonRounded />}</Avatar>
</ListItemAvatar>
<ListItemText
style={{overflow:'hidden', textOverflow:'ellipsis'}}
diff --git a/client/src/components/Header.js b/client/src/components/Header.js
index d245976..c0408a1 100644
--- a/client/src/components/Header.js
+++ b/client/src/components/Header.js
@@ -32,7 +32,7 @@
<Menu
id="simple-menu"
anchorEl={anchorEl}
- keepMounted
+
open={Boolean(anchorEl)}
onClose={handleClose}
>
diff --git a/client/src/components/MessageList.js b/client/src/components/MessageList.js
index d856c17..4841ea1 100644
--- a/client/src/components/MessageList.js
+++ b/client/src/components/MessageList.js
@@ -1,7 +1,7 @@
-import { Avatar, Box, Divider, Typography } from '@material-ui/core'
-import React from 'react'
import Message from './Message'
-import PersonIcon from '@material-ui/icons/PersonRounded'
+import React from 'react'
+import { Avatar, Box, Divider, Typography } from '@material-ui/core'
+import { PersonRounded } from '@material-ui/icons'
export default function MessageList(props) {
const displayName = props.conversation.getDisplayName()
@@ -10,7 +10,7 @@
<div className="message-list">
<Box>
<Box style={{ display: 'inline-block', margin: 16, verticalAlign: 'middle' }}>
- <Avatar>{displayName ? displayName[0].toUpperCase() : <PersonIcon />}</Avatar>
+ <Avatar>{displayName ? displayName[0].toUpperCase() : <PersonRounded />}</Avatar>
</Box>
<Box style={{ display: 'inline-block', verticalAlign: 'middle' }}>
<Typography variant="h5">{displayName}</Typography>
diff --git a/client/src/components/NewContactForm.js b/client/src/components/NewContactForm.js
index c98c9b4..5636be2 100644
--- a/client/src/components/NewContactForm.js
+++ b/client/src/components/NewContactForm.js
@@ -1,7 +1,6 @@
import React from 'react'
-import SearchIcon from '@material-ui/icons/Search';
-import InputBase from '@material-ui/core/InputBase';
-import InputAdornment from '@material-ui/core/InputAdornment';
+import { InputBase, InputAdornment } from '@material-ui/core';
+import { SearchRounded } from '@material-ui/icons';
class NewContactForm extends React.Component {
constructor(props) {
@@ -40,11 +39,8 @@
type="search"
placeholder="Ajouter un contact"
onChange={this.handleChange}
- startAdornment={
- <InputAdornment position="start">
- <SearchIcon />
- </InputAdornment>
- } />
+ startAdornment={<InputAdornment position="start"><SearchRounded /></InputAdornment>}
+ />
</form>
)
}
diff --git a/client/src/components/SendMessageForm.js b/client/src/components/SendMessageForm.js
index 6269e3b..48770ba 100644
--- a/client/src/components/SendMessageForm.js
+++ b/client/src/components/SendMessageForm.js
@@ -1,8 +1,7 @@
import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { IconButton, InputBase, Paper, Popper } from '@material-ui/core'
-import SendIcon from '@material-ui/icons/Send'
-import EmojiIcon from '@material-ui/icons/EmojiEmotionsRounded'
+import { Send, EmojiEmotionsRounded } from '@material-ui/icons'
import EmojiPicker from 'emoji-picker-react'
const useStyles = makeStyles((theme) => ({
@@ -58,7 +57,7 @@
className="send-message-card"
className={classes.root}>
<IconButton aria-describedby={id} variant="contained" color="primary" onClick={handleOpenEmojiPicker}>
- <EmojiIcon />
+ <EmojiEmotionsRounded />
</IconButton>
<Popper
id={id}
@@ -66,7 +65,7 @@
anchorEl={anchorEl}
onClose={handleClose}
>
- <EmojiPicker
+ <EmojiPicker.default
onEmojiClick={onEmojiClick}
disableAutoFocus={true}
disableSkinTonePicker={true}
@@ -82,7 +81,7 @@
onChange={handleInputChange}
/>
<IconButton type="submit" className={classes.iconButton} aria-label="search">
- <SendIcon />
+ <Send />
</IconButton>
</Paper>
</div>
diff --git a/client/src/index.js b/client/src/index.js
index f4c1f23..054afae 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -1,24 +1,30 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.scss';
-import App from './App';
-//import * as serviceWorker from './serviceWorker';
-const rootEl = document.getElementById('root');
+'use strict'
+import React from 'react'
+import ReactDOM from 'react-dom'
+import { BrowserRouter as Router } from 'react-router-dom'
+import App from './App.js'
+import './index.scss'
+
+//import * as serviceWorker from './serviceWorker'
+const rootEl = document.getElementById('root')
const render = Component =>
ReactDOM.render(
<React.StrictMode>
+ <Router>
<Component />
+ </Router>
</React.StrictMode>,
rootEl
-);
+)
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
-//serviceWorker.unregister();
+//serviceWorker.unregister()
render(App)
-if (module.hot) module.hot.accept('./App', () => {
+
+if (import.meta.webpackHot) import.meta.webpackHot.accept('./App', () => {
try {
render(App)
} catch (e) {
diff --git a/client/src/pages/loginDialog.jsx b/client/src/pages/loginDialog.jsx
index 93f9f59..4e15ae1 100644
--- a/client/src/pages/loginDialog.jsx
+++ b/client/src/pages/loginDialog.jsx
@@ -105,7 +105,7 @@
submitted: true,
loading: true
})
- authManager.authenticate()
+ authManager.authenticate('admin', 'admin')
/*fetch('/api/localLogin?username=none&password=none', {
header: { "Content-Type": "application/json" },
method: "POST",
diff --git a/client/src/pages/serverSetup.jsx b/client/src/pages/serverSetup.jsx
new file mode 100644
index 0000000..70f9342
--- /dev/null
+++ b/client/src/pages/serverSetup.jsx
@@ -0,0 +1,85 @@
+import React, { useState } from 'react';
+import { useHistory } from "react-router-dom";
+
+import { Box, Container, Fab, Card, CardContent, Typography, Input } from '@material-ui/core';
+import GroupAddRounded from '@material-ui/icons/GroupAddRounded';
+import { makeStyles } from '@material-ui/core/styles';
+import authManager from '../AuthManager'
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ '& > *': {
+ margin: theme.spacing(1),
+ },
+ },
+ extendedIcon: {
+ marginRight: theme.spacing(1),
+ },
+ wizardCard: {
+ borderRadius: 8,
+ maxWidth: 360,
+ margin: "16px auto"
+ }, textField: {
+ margin: theme.spacing(1),
+ }
+}))
+
+export default function ServerSetup(props) {
+ const classes = useStyles()
+ const history = useHistory();
+ const [password, setPassword] = useState('');
+ const [passwordRepeat, setPasswordRepeat] = useState('');
+
+ const isValid = () => password && password === passwordRepeat
+
+ const handleSubmit = async e => {
+ e.preventDefault()
+ if (!isValid())
+ return
+ if (await authManager.setup(password)) {
+ history.replace('/')
+ }
+ }
+
+ return (
+ <Container className='message-list'>
+ <Card className={classes.wizardCard}>
+ <CardContent component="form" onSubmit={handleSubmit}>
+ <Typography gutterBottom variant="h5" component="h2">
+ Jami Web Node setup
+ </Typography>
+ <Typography variant="body2" color="textSecondary" component="p">
+ Welcome to the Jami web node setup.<br/>
+ Let's start by creating a new administrator account to control access to the server configuration.
+ </Typography>
+
+ <Typography variant='body1'></Typography>
+ <div><Input className={classes.textField} value="admin" name="username" autoComplete="username" disabled /></div>
+ <div><Input
+ className={classes.textField}
+ value={password}
+ onChange={e => setPassword(e.target.value)}
+ name="password"
+ type='password'
+ placeholder="New password"
+ autoComplete="new-password" />
+ </div>
+ <div><Input
+ className={classes.textField}
+ value={passwordRepeat}
+ onChange={e => setPasswordRepeat(e.target.value)}
+ name="password"
+ error={!!passwordRepeat && !isValid()}
+ type='password'
+ placeholder="Repeat password"
+ autoComplete="new-password" /></div>
+ <Box style={{ textAlign: 'center', marginTop: 16 }}>
+ <Fab variant='extended' color='primary' type='submit' disabled={!isValid()}>
+ <GroupAddRounded className={classes.extendedIcon} />
+ Create admin account
+ </Fab>
+ </Box>
+ </CardContent>
+ </Card>
+ </Container>)
+}
diff --git a/client/webpack.config.js b/client/webpack.config.js
index f3b38cd..82caf43 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -1,27 +1,38 @@
'use strict'
-const path = require('path')
-require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') })
-const HtmlWebpackPlugin = require('html-webpack-plugin')
+
+import dotenv from 'dotenv'
+dotenv.config({ path: resolve(import.meta.url, '..', '.env') })
+
+import { resolve } from 'path'
+import HtmlWebpackPlugin from 'html-webpack-plugin'
+
+import { fileURLToPath } from 'url';
+import { dirname } from 'path';
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
const mode = process.env.NODE_ENV || 'development'
-let entry = [path.resolve(__dirname, 'src', 'index.js')]
+let entry = [resolve(__dirname, 'src', 'index.js')]
let plugins = [new HtmlWebpackPlugin({
- template: path.resolve(__dirname, 'src', 'index.ejs')
+ template: resolve(__dirname, 'src', 'index.ejs')
})]
let devtool = undefined
+let babelLoaderPlugins = ["@babel/plugin-transform-runtime"]
if (mode === 'development') {
- const webpack = require('webpack')
- entry = ['react-hot-loader/patch', 'webpack-hot-middleware/client', ...entry]
- plugins = [new webpack.HotModuleReplacementPlugin(), ...plugins]
+ const webpack = (await import('webpack')).default
+ const ReactRefreshWebpackPlugin = (await import('@pmmmwh/react-refresh-webpack-plugin')).default
+ entry = ['webpack-hot-middleware/client', ...entry]
+ plugins = [new webpack.HotModuleReplacementPlugin(), new ReactRefreshWebpackPlugin(), ...plugins]
+ babelLoaderPlugins = [...babelLoaderPlugins, "react-refresh/babel"]
devtool = 'inline-source-map'
}
console.log(`Webpack configured for ${mode}`)
-module.exports = {
+export default {
entry,
output: {
- path: path.resolve(__dirname, 'dist'),
+ path: resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/'
},
@@ -31,14 +42,20 @@
rules: [
{
test: /\.jsx?/,
+ resolve: {
+ fullySpecified: false
+ },
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
- presets: [['@babel/preset-env', {
- useBuiltIns: 'entry',
- corejs:{ version: "3.10", proposals: true },
- }], '@babel/preset-react']
+ plugins: babelLoaderPlugins,
+ presets: [
+ ['@babel/preset-env', {
+ useBuiltIns: 'entry',
+ corejs:{ version: "3.10", proposals: true },
+ }],
+ '@babel/preset-react']
}
}
},
diff --git a/model/Account.js b/model/Account.js
index 1f70c33..46f96ed 100644
--- a/model/Account.js
+++ b/model/Account.js
@@ -1,4 +1,4 @@
-const Contact = require('./Contact')
+import Contact from './Contact.js'
class Account {
constructor(id, details, volatileDetails) {
@@ -52,6 +52,10 @@
return this.getRegisteredName() || this.getUri()
}
+ getDisplayNameNoFallback() {
+ return this.details["Account.displayName"] || this.getRegisteredName()
+ }
+
getConversationIds() {
return Object.keys(this.conversations)
}
@@ -91,4 +95,4 @@
Account.BOOL_TRUE = "true"
Account.BOOL_FALSE = "false"
-module.exports = Account
+export default Account
diff --git a/model/Contact.js b/model/Contact.js
index 9d00098..8fa26b2 100644
--- a/model/Contact.js
+++ b/model/Contact.js
@@ -30,4 +30,4 @@
}
}
-module.exports = Contact;
+export default Contact
diff --git a/model/Conversation.js b/model/Conversation.js
index 22dc477..09fb76f 100644
--- a/model/Conversation.js
+++ b/model/Conversation.js
@@ -1,4 +1,4 @@
-const Contact = require('./Contact')
+import Contact from './Contact.js'
class Conversation {
constructor(id, accountId, members) {
@@ -62,4 +62,4 @@
}
}
-module.exports = Conversation;
+export default Conversation;
diff --git a/package-lock.json b/package-lock.json
index 4b4e8fc..2042d1f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,19 +34,18 @@
"jami-web-client": "file:client",
"llnode": "^3.2.0",
"nodemon": "^2.0.7",
- "react-hot-loader": "^4.13.0",
"webpack-dev-middleware": "^4.1.0",
"webpack-hot-middleware": "^2.25.0"
}
},
"client": {
- "name": "jami-web-client",
"version": "0.1.0",
"dev": true,
"dependencies": {
- "@material-ui/core": "^4.10.2",
- "@material-ui/icons": "^4.9.1",
- "@material-ui/lab": "^4.0.0-alpha.56",
+ "@babel/runtime": "^7.13.10",
+ "@material-ui/core": "^4.11.3",
+ "@material-ui/icons": "^4.11.2",
+ "@material-ui/lab": "^4.0.0-alpha.57",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
@@ -60,11 +59,14 @@
},
"devDependencies": {
"@babel/core": "^7.13.14",
+ "@babel/plugin-transform-runtime": "^7.13.15",
"@babel/preset-env": "^7.13.12",
"@babel/preset-react": "^7.13.13",
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.0-beta.3",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.0",
"html-webpack-plugin": "^5.3.1",
+ "react-refresh": "^0.10.0",
"sass": "^1.32.8",
"sass-loader": "^11.0.1",
"style-loader": "^2.0.0",
@@ -72,6 +74,84 @@
"webpack-cli": "^4.6.0"
}
},
+ "client/node_modules/@pmmmwh/react-refresh-webpack-plugin": {
+ "version": "0.5.0-beta.3",
+ "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.0-beta.3.tgz",
+ "integrity": "sha512-21vRTjPQC/Z9S6ecmRLlo/VvnLNkWdUIU6AUaouZjYVOH/vMcjDUx6LWdCqBdibL7fRygYIaUEMevO4rjcvO5w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-html": "^0.0.7",
+ "core-js-pure": "^3.8.1",
+ "error-stack-parser": "^2.0.6",
+ "html-entities": "^2.1.0",
+ "loader-utils": "^2.0.0",
+ "native-url": "^0.3.4",
+ "schema-utils": "^3.0.0",
+ "source-map": "^0.7.3"
+ },
+ "engines": {
+ "node": ">= 10.13"
+ },
+ "peerDependencies": {
+ "@types/webpack": "4.x",
+ "react-refresh": "^0.10.0",
+ "sockjs-client": "^1.4.0",
+ "type-fest": "^1.0.2",
+ "webpack": ">=4.43.0 <6.0.0",
+ "webpack-dev-server": "3.x || 4.x",
+ "webpack-hot-middleware": "2.x",
+ "webpack-plugin-serve": "0.x || 1.x"
+ },
+ "peerDependenciesMeta": {
+ "@types/webpack": {
+ "optional": true
+ },
+ "sockjs-client": {
+ "optional": true
+ },
+ "type-fest": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ },
+ "webpack-hot-middleware": {
+ "optional": true
+ },
+ "webpack-plugin-serve": {
+ "optional": true
+ }
+ }
+ },
+ "client/node_modules/html-entities": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
+ "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
+ "dev": true
+ },
+ "client/node_modules/source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "client/node_modules/type-fest": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.0.2.tgz",
+ "integrity": "sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w==",
+ "dev": true,
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
@@ -149,6 +229,15 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/@babel/core/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/@babel/generator": {
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz",
@@ -160,6 +249,15 @@
"source-map": "^0.5.0"
}
},
+ "node_modules/@babel/generator/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/@babel/helper-annotate-as-pure": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz",
@@ -1242,6 +1340,32 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-runtime": {
+ "version": "7.13.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz",
+ "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.13.12",
+ "@babel/helper-plugin-utils": "^7.13.0",
+ "babel-plugin-polyfill-corejs2": "^0.2.0",
+ "babel-plugin-polyfill-corejs3": "^0.2.0",
+ "babel-plugin-polyfill-regenerator": "^0.2.0",
+ "semver": "^6.3.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/@babel/plugin-transform-shorthand-properties": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz",
@@ -1663,6 +1787,7 @@
"resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.57.tgz",
"integrity": "sha512-qo/IuIQOmEKtzmRD2E4Aa6DB4A87kmY6h0uYhjUmrrgmEAgbbw9etXpWPVXuRK6AGIQCjFzV6WO2i21m1R4FCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.2",
@@ -2829,6 +2954,50 @@
"webpack": ">=2"
}
},
+ "node_modules/babel-loader/node_modules/json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/babel-loader/node_modules/loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/babel-loader/node_modules/schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 8.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/babel-plugin-dynamic-import-node": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
@@ -3149,9 +3318,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001208",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz",
- "integrity": "sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==",
+ "version": "1.0.30001210",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001210.tgz",
+ "integrity": "sha512-avmGf0Jo00I8vB0I89J4Pba48kddasErV7slu7wrkyM5uY9gE5P+B+V3hjABv8Hp4YNG2nBqIUFUXlnqNteXEA==",
"dev": true
},
"node_modules/chalk": {
@@ -3242,15 +3411,6 @@
"node": ">= 4.0"
}
},
- "node_modules/clean-css/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/cli-boxes": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -3320,13 +3480,10 @@
"dev": true
},
"node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
},
"node_modules/commondir": {
"version": "1.0.1",
@@ -3541,23 +3698,22 @@
}
},
"node_modules/css-loader": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.1.tgz",
- "integrity": "sha512-YCyRzlt/jgG1xanXZDG/DHqAueOtXFHeusP9TS478oP1J++JSKOyEgGW1GHVoCj/rkS+GWOlBwqQJBr9yajQ9w==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.2.tgz",
+ "integrity": "sha512-IS722y7Lh2Yq+acMR74tdf3faMOLRP2RfLwS0VzSS7T98IHtacMWJLku3A0OBTFHB07zAa4nWBhA8gfxwQVWGQ==",
"dev": true,
"dependencies": {
"camelcase": "^6.2.0",
- "cssesc": "^3.0.0",
"icss-utils": "^5.1.0",
"loader-utils": "^2.0.0",
- "postcss": "^8.2.8",
+ "postcss": "^8.2.10",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",
"postcss-modules-values": "^4.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^3.0.0",
- "semver": "^7.3.4"
+ "semver": "^7.3.5"
},
"engines": {
"node": ">= 10.13.0"
@@ -3582,38 +3738,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/css-loader/node_modules/loader-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
- "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
- "dev": true,
- "dependencies": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- },
- "engines": {
- "node": ">=8.9.0"
- }
- },
- "node_modules/css-loader/node_modules/schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/css-loader/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -3669,15 +3793,6 @@
"integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=",
"dev": true
},
- "node_modules/css/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -3835,12 +3950,6 @@
}
]
},
- "node_modules/dom-walk": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
- "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
- "dev": true
- },
"node_modules/domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
@@ -3994,9 +4103,9 @@
}
},
"node_modules/engine.io-client/node_modules/ws": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
- "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
+ "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==",
"engines": {
"node": ">=8.3.0"
},
@@ -4048,9 +4157,9 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/engine.io/node_modules/ws": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
- "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
+ "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==",
"engines": {
"node": ">=8.3.0"
},
@@ -4121,6 +4230,15 @@
"node": ">=4"
}
},
+ "node_modules/error-stack-parser": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz",
+ "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==",
+ "dev": true,
+ "dependencies": {
+ "stackframe": "^1.1.1"
+ }
+ },
"node_modules/es-module-lexer": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz",
@@ -4360,12 +4478,6 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
"node_modules/fast-xml-parser": {
"version": "3.19.0",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz",
@@ -4571,16 +4683,6 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
- "node_modules/global": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
- "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
- "dev": true,
- "dependencies": {
- "min-document": "^2.19.0",
- "process": "^0.11.10"
- }
- },
"node_modules/global-dirs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
@@ -4758,6 +4860,38 @@
"node": ">=6"
}
},
+ "node_modules/html-minifier-terser/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/html-minifier-terser/node_modules/terser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+ "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "dev": true,
+ "dependencies": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/html-minifier-terser/node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
"node_modules/html-webpack-plugin": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz",
@@ -5664,29 +5798,17 @@
}
},
"node_modules/loader-utils": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
- "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
- "json5": "^1.0.1"
+ "json5": "^2.1.2"
},
"engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/loader-utils/node_modules/json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "dev": true,
- "dependencies": {
- "minimist": "^1.2.0"
- },
- "bin": {
- "json5": "lib/cli.js"
+ "node": ">=8.9.0"
}
},
"node_modules/locate-path": {
@@ -5836,15 +5958,6 @@
"url": "https://github.com/sindresorhus/mem?sponsor=1"
}
},
- "node_modules/mem/node_modules/mimic-fn": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
- "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/memfs": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz",
@@ -5913,12 +6026,12 @@
}
},
"node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
+ "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
"dev": true,
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
"node_modules/mimic-response": {
@@ -5930,15 +6043,6 @@
"node": ">=4"
}
},
- "node_modules/min-document": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
- "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
- "dev": true,
- "dependencies": {
- "dom-walk": "^0.1.0"
- }
- },
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -6124,6 +6228,15 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "node_modules/native-url": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.3.4.tgz",
+ "integrity": "sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==",
+ "dev": true,
+ "dependencies": {
+ "querystring": "^0.2.0"
+ }
+ },
"node_modules/negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -6214,9 +6327,6 @@
},
"bin": {
"nopt": "bin/nopt.js"
- },
- "engines": {
- "node": "*"
}
},
"node_modules/normalize-path": {
@@ -6336,6 +6446,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/onetime/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/optional-require": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz",
@@ -6363,15 +6482,15 @@
}
},
"node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"dependencies": {
- "p-try": "^2.0.0"
+ "yocto-queue": "^0.1.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -6389,6 +6508,21 @@
"node": ">=8"
}
},
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -6681,15 +6815,6 @@
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
"dev": true
},
- "node_modules/postcss/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
@@ -6930,55 +7055,20 @@
"integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
"dev": true
},
- "node_modules/react-hot-loader": {
- "version": "4.13.0",
- "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.0.tgz",
- "integrity": "sha512-JrLlvUPqh6wIkrK2hZDfOyq/Uh/WeVEr8nc7hkn2/3Ul0sx1Kr5y4kOGNacNRoj7RhwLNcQ3Udf1KJXrqc0ZtA==",
- "dev": true,
- "dependencies": {
- "fast-levenshtein": "^2.0.6",
- "global": "^4.3.0",
- "hoist-non-react-statics": "^3.3.0",
- "loader-utils": "^1.1.0",
- "prop-types": "^15.6.1",
- "react-lifecycles-compat": "^3.0.4",
- "shallowequal": "^1.1.0",
- "source-map": "^0.7.3"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "@types/react": "^15.0.0 || ^16.0.0 || ^17.0.0 ",
- "react": "^15.0.0 || ^16.0.0 || ^17.0.0 ",
- "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 "
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-hot-loader/node_modules/source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
- "node_modules/react-lifecycles-compat": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
- "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
- "dev": true
+ "node_modules/react-refresh": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.10.0.tgz",
+ "integrity": "sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/react-router": {
"version": "5.2.0",
@@ -7398,12 +7488,12 @@
}
},
"node_modules/sass": {
- "version": "1.32.8",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.8.tgz",
- "integrity": "sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==",
+ "version": "1.32.10",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.10.tgz",
+ "integrity": "sha512-Nx0pcWoonAkn7CRp0aE/hket1UP97GiR1IFw3kcjV3pnenhWgZEWUf0ZcfPOV2fK52fnOcK3JdC/YYZ9E47DTQ==",
"dev": true,
"dependencies": {
- "chokidar": ">=2.0.0 <4.0.0"
+ "chokidar": ">=3.0.0 <4.0.0"
},
"bin": {
"sass": "sass.js"
@@ -7457,17 +7547,17 @@
}
},
"node_modules/schema-utils": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
- "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
+ "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
"dev": true,
"dependencies": {
- "@types/json-schema": "^7.0.5",
- "ajv": "^6.12.4",
+ "@types/json-schema": "^7.0.6",
+ "ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"engines": {
- "node": ">= 8.9.0"
+ "node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
@@ -7580,12 +7670,6 @@
"node": ">=8"
}
},
- "node_modules/shallowequal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
- "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
- "dev": true
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7743,9 +7827,9 @@
"dev": true
},
"node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -7774,15 +7858,6 @@
"source-map": "^0.6.0"
}
},
- "node_modules/source-map-support/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/source-map-url": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
@@ -7798,6 +7873,12 @@
"memory-pager": "^1.0.2"
}
},
+ "node_modules/stackframe": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz",
+ "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==",
+ "dev": true
+ },
"node_modules/statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
@@ -7901,38 +7982,6 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
- "node_modules/style-loader/node_modules/loader-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
- "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
- "dev": true,
- "dependencies": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- },
- "engines": {
- "node": ">=8.9.0"
- }
- },
- "node_modules/style-loader/node_modules/schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -7976,20 +8025,20 @@
}
},
"node_modules/terser": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
- "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz",
+ "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==",
"dev": true,
"dependencies": {
"commander": "^2.20.0",
- "source-map": "~0.6.1",
- "source-map-support": "~0.5.12"
+ "source-map": "~0.7.2",
+ "source-map-support": "~0.5.19"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=10"
}
},
"node_modules/terser-webpack-plugin": {
@@ -8016,72 +8065,7 @@
"webpack": "^5.1.0"
}
},
- "node_modules/terser-webpack-plugin/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "node_modules/terser-webpack-plugin/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/terser": {
- "version": "5.6.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz",
- "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==",
- "dev": true,
- "dependencies": {
- "commander": "^2.20.0",
- "source-map": "~0.7.2",
- "source-map-support": "~0.5.19"
- },
- "bin": {
- "terser": "bin/terser"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/terser/node_modules/source-map": {
+ "node_modules/terser/node_modules/source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
@@ -8090,21 +8074,6 @@
"node": ">= 8"
}
},
- "node_modules/terser/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "node_modules/terser/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/tiny-invariant": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
@@ -8571,24 +8540,6 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
- "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/webpack-hot-middleware": {
"version": "2.25.0",
"resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz",
@@ -8648,33 +8599,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/webpack-sources/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/webpack/node_modules/schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/websocket-driver": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
@@ -8863,6 +8787,12 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
@@ -8875,6 +8805,14 @@
"@babel/types": "^7.13.0",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
}
},
"@babel/helper-annotate-as-pure": {
@@ -9756,6 +9694,28 @@
"@babel/helper-plugin-utils": "^7.12.13"
}
},
+ "@babel/plugin-transform-runtime": {
+ "version": "7.13.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz",
+ "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.13.12",
+ "@babel/helper-plugin-utils": "^7.13.0",
+ "babel-plugin-polyfill-corejs2": "^0.2.0",
+ "babel-plugin-polyfill-corejs3": "^0.2.0",
+ "babel-plugin-polyfill-regenerator": "^0.2.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
"@babel/plugin-transform-shorthand-properties": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz",
@@ -11055,6 +11015,39 @@
"loader-utils": "^1.4.0",
"make-dir": "^3.1.0",
"schema-utils": "^2.6.5"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ }
+ },
+ "schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
}
},
"babel-plugin-dynamic-import-node": {
@@ -11311,9 +11304,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001208",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz",
- "integrity": "sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==",
+ "version": "1.0.30001210",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001210.tgz",
+ "integrity": "sha512-avmGf0Jo00I8vB0I89J4Pba48kddasErV7slu7wrkyM5uY9gE5P+B+V3hjABv8Hp4YNG2nBqIUFUXlnqNteXEA==",
"dev": true
},
"chalk": {
@@ -11384,14 +11377,6 @@
"dev": true,
"requires": {
"source-map": "~0.6.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
}
},
"cli-boxes": {
@@ -11448,9 +11433,9 @@
"dev": true
},
"commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"commondir": {
@@ -11618,34 +11603,25 @@
"source-map": "^0.6.1",
"source-map-resolve": "^0.5.2",
"urix": "^0.1.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
}
},
"css-loader": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.1.tgz",
- "integrity": "sha512-YCyRzlt/jgG1xanXZDG/DHqAueOtXFHeusP9TS478oP1J++JSKOyEgGW1GHVoCj/rkS+GWOlBwqQJBr9yajQ9w==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.2.tgz",
+ "integrity": "sha512-IS722y7Lh2Yq+acMR74tdf3faMOLRP2RfLwS0VzSS7T98IHtacMWJLku3A0OBTFHB07zAa4nWBhA8gfxwQVWGQ==",
"dev": true,
"requires": {
"camelcase": "^6.2.0",
- "cssesc": "^3.0.0",
"icss-utils": "^5.1.0",
"loader-utils": "^2.0.0",
- "postcss": "^8.2.8",
+ "postcss": "^8.2.10",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",
"postcss-modules-values": "^4.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^3.0.0",
- "semver": "^7.3.4"
+ "semver": "^7.3.5"
},
"dependencies": {
"camelcase": {
@@ -11654,28 +11630,6 @@
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
"dev": true
},
- "loader-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
- "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
- "dev": true,
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- }
- },
- "schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "requires": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- }
- },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -11849,12 +11803,6 @@
}
}
},
- "dom-walk": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
- "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
- "dev": true
- },
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
@@ -11985,9 +11933,9 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"ws": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
- "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
+ "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==",
"requires": {}
}
}
@@ -12019,9 +11967,9 @@
}
},
"ws": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
- "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
+ "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==",
"requires": {}
}
}
@@ -12074,6 +12022,15 @@
"integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
"dev": true
},
+ "error-stack-parser": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz",
+ "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==",
+ "dev": true,
+ "requires": {
+ "stackframe": "^1.1.1"
+ }
+ },
"es-module-lexer": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz",
@@ -12262,12 +12219,6 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
"fast-xml-parser": {
"version": "3.19.0",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz",
@@ -12420,16 +12371,6 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
- "global": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
- "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
- "dev": true,
- "requires": {
- "min-document": "^2.19.0",
- "process": "^0.11.10"
- }
- },
"global-dirs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
@@ -12573,6 +12514,33 @@
"param-case": "^3.0.3",
"relateurl": "^0.2.7",
"terser": "^4.6.3"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ },
+ "terser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+ "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ }
+ }
+ }
}
},
"html-webpack-plugin": {
@@ -12892,11 +12860,14 @@
"version": "file:client",
"requires": {
"@babel/core": "^7.13.14",
+ "@babel/plugin-transform-runtime": "^7.13.15",
"@babel/preset-env": "^7.13.12",
"@babel/preset-react": "^7.13.13",
- "@material-ui/core": "^4.10.2",
- "@material-ui/icons": "^4.9.1",
- "@material-ui/lab": "^4.0.0-alpha.56",
+ "@babel/runtime": "^7.13.10",
+ "@material-ui/core": "^4.11.3",
+ "@material-ui/icons": "^4.11.2",
+ "@material-ui/lab": "^4.0.0-alpha.57",
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.0-beta.3",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
@@ -12907,6 +12878,7 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-emoji-render": "^1.2.4",
+ "react-refresh": "^0.10.0",
"react-router-dom": "^5.2.0",
"react-sound": "^1.2.0",
"sass": "^1.32.8",
@@ -12915,6 +12887,44 @@
"style-loader": "^2.0.0",
"webpack": "^5.31.0",
"webpack-cli": "^4.6.0"
+ },
+ "dependencies": {
+ "@pmmmwh/react-refresh-webpack-plugin": {
+ "version": "0.5.0-beta.3",
+ "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.0-beta.3.tgz",
+ "integrity": "sha512-21vRTjPQC/Z9S6ecmRLlo/VvnLNkWdUIU6AUaouZjYVOH/vMcjDUx6LWdCqBdibL7fRygYIaUEMevO4rjcvO5w==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "^0.0.7",
+ "core-js-pure": "^3.8.1",
+ "error-stack-parser": "^2.0.6",
+ "html-entities": "^2.1.0",
+ "loader-utils": "^2.0.0",
+ "native-url": "^0.3.4",
+ "schema-utils": "^3.0.0",
+ "source-map": "^0.7.3"
+ }
+ },
+ "html-entities": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
+ "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.0.2.tgz",
+ "integrity": "sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w==",
+ "dev": true,
+ "optional": true,
+ "peer": true
+ }
}
},
"jest-diff": {
@@ -13343,25 +13353,14 @@
"dev": true
},
"loader-utils": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
- "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
- "json5": "^1.0.1"
- },
- "dependencies": {
- "json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0"
- }
- }
+ "json5": "^2.1.2"
}
},
"locate-path": {
@@ -13475,14 +13474,6 @@
"requires": {
"map-age-cleaner": "^0.1.3",
"mimic-fn": "^3.1.0"
- },
- "dependencies": {
- "mimic-fn": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
- "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
- "dev": true
- }
}
},
"memfs": {
@@ -13535,9 +13526,9 @@
}
},
"mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
+ "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
"dev": true
},
"mimic-response": {
@@ -13546,15 +13537,6 @@
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"dev": true
},
- "min-document": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
- "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
- "dev": true,
- "requires": {
- "dom-walk": "^0.1.0"
- }
- },
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -13674,6 +13656,15 @@
"integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==",
"dev": true
},
+ "native-url": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.3.4.tgz",
+ "integrity": "sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==",
+ "dev": true,
+ "requires": {
+ "querystring": "^0.2.0"
+ }
+ },
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -13833,6 +13824,14 @@
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
+ },
+ "dependencies": {
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ }
}
},
"optional-require": {
@@ -13853,12 +13852,12 @@
"dev": true
},
"p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"requires": {
- "p-try": "^2.0.0"
+ "yocto-queue": "^0.1.0"
}
},
"p-locate": {
@@ -13868,6 +13867,17 @@
"dev": true,
"requires": {
"p-limit": "^2.2.0"
+ },
+ "dependencies": {
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ }
}
},
"p-try": {
@@ -14036,14 +14046,6 @@
"colorette": "^1.2.2",
"nanoid": "^3.1.22",
"source-map": "^0.6.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
}
},
"postcss-modules-extract-imports": {
@@ -14298,40 +14300,16 @@
}
}
},
- "react-hot-loader": {
- "version": "4.13.0",
- "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.0.tgz",
- "integrity": "sha512-JrLlvUPqh6wIkrK2hZDfOyq/Uh/WeVEr8nc7hkn2/3Ul0sx1Kr5y4kOGNacNRoj7RhwLNcQ3Udf1KJXrqc0ZtA==",
- "dev": true,
- "requires": {
- "fast-levenshtein": "^2.0.6",
- "global": "^4.3.0",
- "hoist-non-react-statics": "^3.3.0",
- "loader-utils": "^1.1.0",
- "prop-types": "^15.6.1",
- "react-lifecycles-compat": "^3.0.4",
- "shallowequal": "^1.1.0",
- "source-map": "^0.7.3"
- },
- "dependencies": {
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
- }
- }
- },
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
- "react-lifecycles-compat": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
- "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
+ "react-refresh": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.10.0.tgz",
+ "integrity": "sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==",
"dev": true
},
"react-router": {
@@ -14683,12 +14661,12 @@
}
},
"sass": {
- "version": "1.32.8",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.8.tgz",
- "integrity": "sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==",
+ "version": "1.32.10",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.10.tgz",
+ "integrity": "sha512-Nx0pcWoonAkn7CRp0aE/hket1UP97GiR1IFw3kcjV3pnenhWgZEWUf0ZcfPOV2fK52fnOcK3JdC/YYZ9E47DTQ==",
"dev": true,
"requires": {
- "chokidar": ">=2.0.0 <4.0.0"
+ "chokidar": ">=3.0.0 <4.0.0"
}
},
"sass-loader": {
@@ -14712,13 +14690,13 @@
}
},
"schema-utils": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
- "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
+ "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
"dev": true,
"requires": {
- "@types/json-schema": "^7.0.5",
- "ajv": "^6.12.4",
+ "@types/json-schema": "^7.0.6",
+ "ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
},
@@ -14811,12 +14789,6 @@
"kind-of": "^6.0.2"
}
},
- "shallowequal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
- "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
- "dev": true
- },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -14972,9 +14944,9 @@
"dev": true
},
"source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-resolve": {
@@ -14998,14 +14970,6 @@
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
}
},
"source-map-url": {
@@ -15023,6 +14987,12 @@
"memory-pager": "^1.0.2"
}
},
+ "stackframe": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz",
+ "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==",
+ "dev": true
+ },
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
@@ -15096,30 +15066,6 @@
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
- },
- "dependencies": {
- "loader-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
- "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
- "dev": true,
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- }
- },
- "schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "requires": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- }
- }
}
},
"supports-color": {
@@ -15150,26 +15096,20 @@
"dev": true
},
"terser": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
- "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz",
+ "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==",
"dev": true,
"requires": {
"commander": "^2.20.0",
- "source-map": "~0.6.1",
- "source-map-support": "~0.5.12"
+ "source-map": "~0.7.2",
+ "source-map-support": "~0.5.19"
},
"dependencies": {
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
"source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
}
}
@@ -15186,59 +15126,6 @@
"serialize-javascript": "^5.0.1",
"source-map": "^0.6.1",
"terser": "^5.5.1"
- },
- "dependencies": {
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "requires": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "terser": {
- "version": "5.6.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz",
- "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==",
- "dev": true,
- "requires": {
- "commander": "^2.20.0",
- "source-map": "~0.7.2",
- "source-map-support": "~0.5.19"
- },
- "dependencies": {
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
- }
- }
- }
}
},
"tiny-invariant": {
@@ -15542,19 +15429,6 @@
"terser-webpack-plugin": "^5.1.1",
"watchpack": "^2.0.0",
"webpack-sources": "^2.1.1"
- },
- "dependencies": {
- "schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "requires": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- }
- }
}
},
"webpack-cli": {
@@ -15599,19 +15473,6 @@
"mime-types": "^2.1.28",
"range-parser": "^1.2.1",
"schema-utils": "^3.0.0"
- },
- "dependencies": {
- "schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
- "requires": {
- "@types/json-schema": "^7.0.6",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- }
- }
}
},
"webpack-hot-middleware": {
@@ -15661,14 +15522,6 @@
"requires": {
"source-list-map": "^2.0.1",
"source-map": "^0.6.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
}
},
"websocket-driver": {
diff --git a/package.json b/package.json
index 16825dd..75c81f2 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
{
"name": "jami-web-server",
+ "type": "module",
"version": "1.0.0",
"description": "Jaas Web API that handles client requests to Jami daemon",
"main": "index.js",
@@ -29,7 +30,6 @@
"jami-web-client": "file:client",
"llnode": "^3.2.0",
"nodemon": "^2.0.7",
- "react-hot-loader": "^4.13.0",
"webpack-dev-middleware": "^4.1.0",
"webpack-hot-middleware": "^2.25.0"
},
diff --git a/routes/index.js b/routes/index.js
index 01e6c07..cd9bc45 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -1,10 +1,14 @@
-const express = require('express');
-const router = express.Router();
-const path = require('path');
+import { Router } from 'express'
+const router = Router()
+import { join } from 'path'
+import { fileURLToPath } from 'url';
+import { dirname } from 'path';
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
/* GET React App */
router.get(['/app', '/app/*'], (req, res, next) => {
- res.sendFile(path.join(__dirname, '../public', 'index.html'));
-});
+ res.sendFile(join(__dirname, '../public', 'index.html'))
+})
-module.exports = router;
+export default router
diff --git a/routes/jami.js b/routes/jami.js
index 5d50002..674a688 100644
--- a/routes/jami.js
+++ b/routes/jami.js
@@ -1,4 +1,4 @@
-const express = require('express')
+import { Router } from 'express'
class JamiRestApi {
constructor(jami) {
@@ -6,17 +6,28 @@
}
getRouter() {
- const router = express.Router({mergeParams: true})
- router.use(express.json());
+ const router = Router({mergeParams: true})
+ //router.use(express.json());
// Accounts
router.get(['/accounts'], (req, res, next) => {
console.log("Get account list")
- res.json(this.jami.getAccountList().map(account => account.getSummary()))
+ let accounts = this.jami.getAccountList()
+ if (req.user.accountFilter)
+ accounts = accounts.filter(account => req.user.accountFilter(account.getId()))
+ res.json(accounts.map(account => account.getSummary()))
})
- const accountRouter = express.Router({mergeParams: true})
- router.use('/accounts/:accountId', accountRouter)
+ const checkAccount = (req, res, next) => {
+ console.log(`checkAccount ${req.params.accountId} for ${req.user.id}`)
+ if (req.user && (!req.user.accountFilter || req.user.accountFilter(req.params.accountId))) {
+ return next();
+ }
+ res.status(403).end()
+ }
+
+ const accountRouter = Router({mergeParams: true})
+ router.use('/accounts/:accountId', checkAccount, accountRouter)
accountRouter.get(['/'], (req, res, next) => {
console.log(`Get account ${req.params.accountId}`)
@@ -24,7 +35,7 @@
if (account)
res.json(account.getObject())
else
- res.sendStatus(404)
+ res.status(404).end()
})
// Contacts
@@ -34,7 +45,7 @@
if (account)
res.json(account.getContacts())
else
- res.sendStatus(404)
+ res.status(404).end()
})
// Conversations
@@ -42,7 +53,7 @@
console.log(`Get conversations for account ${req.params.accountId}`)
const account = this.jami.getAccount(req.params.accountId)
if (!account)
- res.sendStatus(404)
+ return res.sendStatus(404)
const conversations = account.getConversations()
res.json(Object.keys(conversations).map(conversationId => conversations[conversationId].getObject({
memberFilter: member => member.contact.getUri() !== account.getUri()
@@ -55,22 +66,22 @@
console.log(req.body)
const account = this.jami.getAccount(req.params.accountId)
if (!account)
- res.sendStatus(404)
+ return res.sendStatus(404)
if (req.body.members.length === 1) {
const details = this.jami.addContact(req.params.accountId, req.body.members[0])
res.json(details)
} else
- res.sendStatus(400)
+ res.status(400).end()
})
accountRouter.get('/conversations/:conversationId', (req, res, next) => {
console.log(`Get conversation ${req.params.conversationId} for account ${req.params.accountId}`)
const account = this.jami.getAccount(req.params.accountId)
if (!account)
- res.sendStatus(404)
+ return res.sendStatus(404)
const conversation = account.getConversation(req.params.conversationId)
if (!conversation)
- res.sendStatus(404)
+ res.status(404).end()
else {
res.json(conversation.getObject({
memberFilter: member => member.contact.getUri() !== account.getUri()
@@ -79,7 +90,7 @@
})
// Nameserver
- const nsRouter = express.Router({mergeParams: true})
+ const nsRouter = Router({mergeParams: true})
accountRouter.use('/ns', nsRouter)
nsRouter.get(['/name/:nameQuery'], (req, res, next) => {
@@ -115,4 +126,4 @@
}
}
-module.exports = JamiRestApi
+export default JamiRestApi