diff --git a/.circleci/config.yml b/.circleci/config.yml index 3bf986cca..13d339892 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,17 +2,23 @@ # # Check https://circleci.com/docs/2.0/language-javascript/ for more details # -version: 2 +version: 2.1 + +orbs: + node: circleci/node@3.0.0 + jobs: build: docker: - - image: circleci/node:16.10.0 - - image: circleci/mongo:4.4 + - image: cimg/node:16.11.0 + - image: mongo:4.4 - working_directory: ~/repo + working_directory: ~/homebrewery + executor: node/default steps: - - checkout + - checkout: + path: ~/homebrewery # Download and cache dependencies - restore_cache: @@ -21,12 +27,48 @@ jobs: # fallback to using the latest cache if no exact match is found - v1-dependencies- - - run: npm install + - node/install-npm + - node/install-packages: + app-dir: ~/homebrewery + cache-path: node_modules + override-ci-command: npm i - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }} + - persist_to_workspace: + root: . + paths: + - . + + test: + docker: + - image: cimg/node:16.11.0 + + working_directory: ~/homebrewery + parallelism: 4 + + steps: + - attach_workspace: + at: . + # run tests! - - run: npm run circleci + - run: + name: Test - Basic + command: npm run test:basic + - run: + name: Test - Mustache Spans + command: npm run test:mustache-span + - run: + name: Test - Routes + command: npm run test:route + +workflows: + build_and_test: + jobs: + - build + - test: + requires: + - build \ No newline at end of file diff --git a/README.md b/README.md index 9a5faeaf4..35f0150d1 100644 --- a/README.md +++ b/README.md @@ -9,37 +9,37 @@ using [Markdown][markdown-url]. It is distributed under the terms of the [MIT Li [markdown-url]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet ## Quick Start -The easiest way to get started using the Homebrewery is to use it +The easiest way to get started using The Homebrewery is to use it [on our website][homebrewery-url]. The code is open source, so feel free to -clone it, tinker with it. If you want to make changes to the code, you can run +clone it and tinker with it. If you want to make changes to the code, you can run your own local version for testing by following the installation instructions below. [homebrewery-url]: https://homebrewery.naturalcrit.com ### Installation -First, install three programs that the Homebrewery requires to run and retrieve +First, install three programs that The Homebrewery requires to run and retrieve updates: 1. install [node](https://nodejs.org/en/) 1. install [mongodb](https://www.mongodb.com/try/download/community) (Community version) - For easiest installation, follow these steps: - 1. In the installer, uncheck the option to run as a service - 1. You can install MongoDB Compass if you want a GUI to view your database documents - 1. Go to the C drive and create a folder called "data" - 1. Inside the "data" folder, create a new folder called "db" - 1. Open a command prompt or other terminal and navigate to your mongodb install folder (c:program files\mongo\server\4.4\bin) - 1. In the command prompt, run "mongod", which will start up your local database server - 1. While MongoD is running, open a second command prompt and navigate to the mongodb install folder - 1. In the second command prompt, run "mongo", which allows you to edit the database - 1. Type `use homebrewery` to create the homebrewery database. You should see `switched to db homebrewery` - 1. Type `db.brews.insert({"title":"test"})` to create a blank document. You should see `WriteResult({ "nInserted" : 1 })` - 1. Search in Windows for "Advanced system settings" and open it - 1. Click "Environment variables", find the "path" variable, and double-click to open it - 1. Click "New" and paste in the path to the mongodb "bin" folder - 1. Click "OK", "OK", "OK" to close all the windows -1. install [git](https://git-scm.com/downloads) (select the option that allows Git to run from the command prompt) + For the easiest installation, follow these steps: + 1. In the installer, uncheck the option to run as a service. + 1. You can install MongoDB Compass if you want a GUI to view your database documents. + 1. Go to the C:\ drive and create a folder called "data". + 1. Inside the "data" folder, create a new folder called "db". + 1. Open a command prompt or other terminal and navigate to your MongoDB install folder (C:\Program Files\Mongo\Server\4.4\bin). + 1. In the command prompt, run "mongod", which will start up your local database server. + 1. While MongoD is running, open a second command prompt and navigate to the MongoDB install folder. + 1. In the second command prompt, run "mongo", which allows you to edit the database. + 1. Type `use homebrewery` to create The Homebrewery database. You should see `switched to db homebrewery`. + 1. Type `db.brews.insert({"title":"test"})` to create a blank document. You should see `WriteResult({ "nInserted" : 1 })`. + 1. Search in Windows for "Advanced system settings" and open it. + 1. Click "Environment variables", find the "path" variable, and double-click to open it. + 1. Click "New" and paste in the path to the MongoDB "bin" folder. + 1. Click "OK" three times to close all the windows. +1. install [git](https://git-scm.com/downloads) (select the option that allows Git to run from the command prompt). Checkout the repo ([documentation][github-clone-repo-docs-url]): ``` @@ -54,7 +54,7 @@ the project to run locally. You can set this temporarily in your shell of choice: * Windows Powershell: `$env:NODE_ENV="local"` * Windows CMD: `set NODE_ENV=local` -* Linux / OSX: `export NODE_ENV=local` +* Linux / macOS: `export NODE_ENV=local` Third, you will need to install the Node dependencies, compile the app, and run it using the two commands: @@ -63,7 +63,7 @@ it using the two commands: 1. `npm start` You should now be able to go to [http://localhost:8000](http://localhost:8000) -in your browser and use the Homebrewery offline. +in your browser and use The Homebrewery offline. ### Running the application via Docker @@ -95,11 +95,11 @@ You can check out the [changelog](./changelog.md). ## License -This project is licensed under the [MIT license](./license). Which means you +This project is licensed under the [MIT license](./license), which means you are free to use The Homebrewery in any way that you want, except for claiming that you made it yourself. -If you wish to sell or in some way gain profit for what's created on this site, +If you wish to sell, or in some way gain profit for, what's created on this site, it's your responsibility to ensure you have the proper licenses/rights for any images or resources used. @@ -108,13 +108,12 @@ images or resources used. You are welcome to contribute to the development and maintenance of the project! There are several ways of doing that: - At the moment, we have a huge backlog of [issues][repo-issues-url] and some - of them are outdated, duplicates or doesn't contain any useful info. In order - to help you can [mark duplicates][github-mark-duplicate-url], try to - reproduce some complex or weird issues, try with finding a workaround for a - reported bug or just mention issue managers team to let them know about - outdated issue via `@naturalcrit/issue-managers`. + of them are outdated, duplicates, or don't contain any useful info. To help, you can [mark duplicates][github-mark-duplicate-url], try to + reproduce some complex or weird issues, try finding a workaround for a + reported bug, or just mention our issue managers team to let them know about + outdated issues via `@naturalcrit/issue-managers`. - Our [subreddit][subreddit-url] is constantly growing and there are number of - bug reports: any help with sorting them out is very welcome. + bug reports. Any help with sorting them out is very welcome. - And of course you can contribute by fixing a bug or implementing a new feature by yourself, we are waiting for your [pull requests][github-pr-docs-url]! diff --git a/changelog.md b/changelog.md index 45f050e01..9fed601f8 100644 --- a/changelog.md +++ b/changelog.md @@ -29,11 +29,43 @@ pre { .page p + pre { margin-top : 0.1cm; } + +.page .openSans { + font-family: 'Open Sans'; + font-size: 0.9em; +} ``` ## changelog For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery). +### Wednesday 27/03/2022 - v3.0.8 +{{taskList +* [x] Style updates to user page. + +* [x] Added a logout button (finally)! You can find it under {{openSans **USERNAME {{fa,fa-user}} → LOGOUT {{fas,fa-power-off}}**}} + + Fixes issues: [#303](https://github.com/naturalcrit/homebrewery/issues/303) + +* [x] Clarified the default text when submitting an issue via Reddit post. + +* [x] Fixed broken Table of Contents links in PDFs. (Thanks lucastucious!) + + Fixes issues: [#1749](https://github.com/naturalcrit/homebrewery/issues/1749) + +* [x] Fixed window resizing causing the edit page divider to get lost off of the edge of the page. + + Fixes issues: [#2053](https://github.com/naturalcrit/homebrewery/issues/2053) + +* [x] Fixed Class Table decorations overlapping main text. + + Fixes issues: [#1985](https://github.com/naturalcrit/homebrewery/issues/1985) + +* [x] Updated {{openSans **STYLE EDITOR {{fa,fa-pencil-alt}} → REMOVE DROP CAP {{fas,fa-remove-format}}**}} snippet to also remove small-caps first line font. + +* [x] Background work in preparation for brew themes. +}} + ### Wednesday 02/02/2022 - v3.0.7 {{taskList * [x] Revert active line highlighting. @@ -50,7 +82,7 @@ For a full record of development, visit our [Github Page](https://github.com/nat Fixes issues: [#1943](https://github.com/naturalcrit/homebrewery/issues/1943) -* [x] Added a Legacy to V3 migration guide under **NEED HELP? {{fa,fa-question-circle}} → MIGRATE {{fas,fa-file-import}}** +* [x] Added a Legacy to V3 migration guide under {{openSans **NEED HELP? {{fa,fa-question-circle}} → MIGRATE {{fas,fa-file-import}}**}} * [x] Background refactoring and unit tests. }} @@ -61,7 +93,7 @@ For a full record of development, visit our [Github Page](https://github.com/nat Fixes issues: [#1736](https://github.com/naturalcrit/homebrewery/issues/1736) -* [x] Code search/replace `CTRL F / CTRL SHIFT F` +* [x] Code search/replace PC: `CTRL F / CTRL SHIFT F` / Mac: `CMD F / OPTION CMD F` Fixes issues: [#1201](https://github.com/naturalcrit/homebrewery/issues/1201) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index fbd4011c1..bcfc6e52d 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -77,7 +77,7 @@ const MetadataEditor = createClass({ if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return; } - request.delete(`/api/${this.props.metadata.editId}`) + request.delete(`/api/${this.props.metadata.googleId}${this.props.metadata.editId}`) .send() .end(function(err, res){ window.location.href = '/'; diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 54dcf2206..732c06486 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -32,11 +32,14 @@ const Homebrew = createClass({ } }; }, - componentWillMount : function() { - global.account = this.props.account; + + getInitialState : function(){ global.version = this.props.version; + global.account = this.props.account; global.enable_v3 = this.props.enable_v3; + return {}; }, + render : function (){ return ( @@ -46,7 +49,7 @@ const Homebrew = createClass({ }/> }/> }/> - }/> + }/> }/> }/> }/> diff --git a/client/homebrew/navbar/account.navitem.jsx b/client/homebrew/navbar/account.navitem.jsx index 6b4d054df..be92cea92 100644 --- a/client/homebrew/navbar/account.navitem.jsx +++ b/client/homebrew/navbar/account.navitem.jsx @@ -18,11 +18,50 @@ const Account = createClass({ } }, + handleLogout : function(){ + if(confirm('Are you sure you want to log out?')) { + // Reset divider position + window.localStorage.removeItem('naturalcrit-pane-split'); + // Clear login cookie + let domain = ''; + if(window.location?.hostname) { + let domainArray = window.location.hostname.split('.'); + if(domainArray.length > 2){ + domainArray = [''].concat(domainArray.slice(-2)); + } + domain = domainArray.join('.'); + } + document.cookie = `nc_session=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;samesite=lax;${domain ? `domain=${domain}` : ''}`; + window.location = '/'; + } + }, + render : function(){ if(global.account){ - return - {global.account.username} - ; + return + + {global.account.username} + + + brews + + + logout + + ; } return diff --git a/client/homebrew/navbar/help.navitem.jsx b/client/homebrew/navbar/help.navitem.jsx index b4be18319..f84acabde 100644 --- a/client/homebrew/navbar/help.navitem.jsx +++ b/client/homebrew/navbar/help.navitem.jsx @@ -1,6 +1,7 @@ const React = require('react'); const createClass = require('create-react-class'); const _ = require('lodash'); +const dedent = require('dedent-tabs').default; const Nav = require('naturalcrit/nav/nav.jsx'); @@ -10,7 +11,11 @@ module.exports = function(props){ need help? report issue diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index b3255db45..7929bb5e2 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -14,12 +14,10 @@ const Navbar = createClass({ }; }, - componentDidMount : function() { - //const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); - this.setState({ - //showNonChromeWarning : !isChrome, - ver : window.version - }); + getInitialState : function() { + return { + ver : global.version + }; }, /* diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less index a149307e8..95cc04c7a 100644 --- a/client/homebrew/navbar/navbar.less +++ b/client/homebrew/navbar/navbar.less @@ -142,4 +142,7 @@ text-align : center; } } + .account.navItem{ + min-width: 100px; + } } diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx index a89dad11e..f76d14ebe 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx @@ -31,19 +31,11 @@ const BrewItem = createClass({ if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return; } - if(this.props.brew.googleId) { - request.get(`/api/removeGoogle/${this.props.brew.googleId}${this.props.brew.editId}`) - .send() - .end(function(err, res){ - location.reload(); - }); - } else { - request.delete(`/api/${this.props.brew.editId}`) - .send() - .end(function(err, res){ - location.reload(); - }); - } + request.delete(`/api/${this.props.brew.googleId}${this.props.brew.editId}`) + .send() + .end(function(err, res){ + location.reload(); + }); }, renderDeleteBrewLink : function(){ diff --git a/client/homebrew/pages/basePages/listPage/listPage.jsx b/client/homebrew/pages/basePages/listPage/listPage.jsx index e1f300ab2..934d147be 100644 --- a/client/homebrew/pages/basePages/listPage/listPage.jsx +++ b/client/homebrew/pages/basePages/listPage/listPage.jsx @@ -24,7 +24,8 @@ const ListPage = createClass({ return { sortType : 'alpha', sortDir : 'asc', - filterString : '' + filterString : this.props.query?.filter || '', + query : this.props.query }; }, @@ -74,19 +75,35 @@ const ListPage = createClass({ handleFilterTextChange : function(e){ this.setState({ - filterString : e.target.value + filterString : e.target.value, }); + this.updateUrl(e.target.value); return; }, + updateUrl : function(filterTerm){ + const url = new URL(window.location.href); + const urlParams = new URLSearchParams(url.search); + if(urlParams.get('filter') == filterTerm) + return; + if(!filterTerm) + urlParams.delete('filter'); + else + urlParams.set('filter', filterTerm); + url.search = urlParams; + window.history.replaceState(null, null, url); + }, + renderFilterOption : function(){ return ; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 3e1e3bda3..73389de91 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -200,73 +200,18 @@ const EditPage = createClass({ const brew = this.state.brew; brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1; - if(this.state.saveGoogle) { - if(transfer) { - const res = await request - .post('/api/newGoogle/') - .send(brew) - .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Transferring to Google!'); - this.setState({ errors: err, saveGoogle: false }); - }); + const params = `${transfer ? `?transfer${this.state.saveGoogle ? 'To' : 'From'}Google=true` : ''}`; + const res = await request + .put(`/api/update/${brew.editId}${params}`) + .send(brew) + .catch((err)=>{ + console.log('Error Updating Local Brew'); + this.setState({ errors: err }); + }); - if(!res) { return; } - - console.log('Deleting Local Copy'); - await request.delete(`/api/${brew.editId}`) - .send() - .catch((err)=>{ - console.log('Error deleting Local Copy'); - }); - - this.savedBrew = res.body; - history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID - } else { - const res = await request - .put(`/api/updateGoogle/${brew.editId}`) - .send(brew) - .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Saving to Google!'); - this.setState({ errors: err }); - return; - }); - - this.savedBrew = res.body; - } - } else { - if(transfer) { - const res = await request.post('/api') - .send(brew) - .catch((err)=>{ - console.log('Error creating Local Copy'); - this.setState({ errors: err }); - return; - }); - - await request.get(`/api/removeGoogle/${brew.googleId}${brew.editId}`) - .send() - .catch((err)=>{ - console.log('Error Deleting Google Brew'); - }); - - this.savedBrew = res.body; - history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID - } else { - const res = await request - .put(`/api/update/${brew.editId}`) - .send(brew) - .catch((err)=>{ - console.log('Error Updating Local Brew'); - this.setState({ errors: err }); - return; - }); - - this.savedBrew = res.body; - } + this.savedBrew = res.body; + if(transfer) { + history.replaceState(null, null, `/edit/${this.savedBrew.googleId ?? ''}${this.savedBrew.editId}`); } this.setState((prevState)=>({ @@ -331,26 +276,26 @@ const EditPage = createClass({ console.log(errMsg); } catch (e){} - if(this.state.errors.status == '401'){ - return - Oops! -
- You must be signed in to a Google account - to save this to
Google Drive!
- -
- Sign In -
-
-
- Not Now -
-
-
; - } + // if(this.state.errors.status == '401'){ + // return + // Oops! + //
+ // You must be signed in to a Google account + // to save this to
Google Drive!
+ // + //
+ // Sign In + //
+ //
+ //
+ // Not Now + //
+ //
+ //
; + // } - if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.response.req.url.match(/^\/api.*Google.*$/m)){ return Oops!
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 4e3735618..3742d22d2 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -162,45 +162,24 @@ const NewPage = createClass({ const index = brew.text.indexOf('```\n\n'); brew.style = `${brew.style ? `${brew.style}\n` : ''}${brew.text.slice(7, index - 1)}`; brew.text = brew.text.slice(index + 5); - }; + } brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1; - if(this.state.saveGoogle) { - const res = await request - .post('/api/newGoogle/') + const res = await request + .post(`/api${this.state.saveGoogle ? '?transferToGoogle=true' : ''}`) .send(brew) .catch((err)=>{ - console.log(err.status === 401 - ? 'Not signed in!' - : 'Error Creating New Google Brew!'); + console.log(err); this.setState({ isSaving: false, errors: err }); - return; }); + if(!res) return; - brew = res.body; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); - window.location = `/edit/${brew.googleId}${brew.editId}`; - } else { - request.post('/api') - .send(brew) - .end((err, res)=>{ - if(err){ - this.setState({ - isSaving : false - }); - return; - } - window.onbeforeunload = function(){}; - brew = res.body; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); - window.location = `/edit/${brew.editId}`; - }); - } + brew = res.body; + localStorage.removeItem(BREWKEY); + localStorage.removeItem(STYLEKEY); + localStorage.removeItem(METAKEY); + window.location = `/edit/${brew.googleId ?? ''}${brew.editId}`; }, renderSaveButton : function(){ @@ -213,26 +192,26 @@ const NewPage = createClass({ console.log(errMsg); } catch (e){} - if(this.state.errors.status == '401'){ - return - Oops! -
- You must be signed in to a Google account - to save this to
Google Drive!
- -
- Sign In -
-
-
- Not Now -
-
-
; - } + // if(this.state.errors.status == '401'){ + // return + // Oops! + //
+ // You must be signed in to a Google account + // to save this to
Google Drive!
+ // + //
+ // Sign In + //
+ //
+ //
+ // Not Now + //
+ //
+ //
; + // } - if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.response.req.url.match(/^\/api.*Google.*$/m)){ return Oops!
diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx index a78ba11af..6c3af7907 100644 --- a/client/homebrew/pages/userPage/userPage.jsx +++ b/client/homebrew/pages/userPage/userPage.jsx @@ -19,6 +19,7 @@ const UserPage = createClass({ return { username : '', brews : [], + query : '' }; }, getInitialState : function() { @@ -62,7 +63,7 @@ const UserPage = createClass({ }, render : function(){ - return ; + return ; } }); diff --git a/package-lock.json b/package-lock.json index 13970f622..2597ae515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,29 @@ { "name": "homebrewery", - "version": "3.0.7", + "version": "3.0.8", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "3.0.7", + "version": "3.0.8", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.17.2", + "@babel/core": "^7.17.8", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", - "body-parser": "^1.19.1", + "body-parser": "^1.19.2", "classnames": "^2.3.1", - "codemirror": "^5.65.1", + "codemirror": "^5.65.2", "cookie-parser": "^1.4.6", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.1", - "express": "^4.17.2", + "express": "^4.17.3", "express-async-handler": "^1.2.0", - "express-static-gzip": "2.1.3", - "fs-extra": "10.0.0", - "googleapis": "95.0.0", + "express-static-gzip": "2.1.5", + "fs-extra": "10.0.1", + "googleapis": "100.0.0", "js-yaml": "^4.1.0", "jwt-simple": "^0.5.6", "less": "^3.13.1", @@ -32,8 +32,8 @@ "marked-extended-tables": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.29.1", - "mongoose": "^6.2.1", - "nanoid": "3.2.0", + "mongoose": "^6.2.9", + "nanoid": "3.3.2", "nconf": "^0.11.3", "query-string": "7.1.1", "react": "^16.14.0", @@ -45,8 +45,8 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "eslint": "^8.8.0", - "eslint-plugin-react": "^7.28.0", + "eslint": "^8.12.0", + "eslint-plugin-react": "^7.29.4", "jest": "^27.5.1", "supertest": "^6.2.2" }, @@ -55,13 +55,11 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.0.1.tgz", - "integrity": "sha512-EldHF4Ufj3NL9yCAmYrPzY+3/Yqrzxu24F4Mu4nRjK3w70AKYRmhuLwGZdA9JeoDsbIwkgGkbqUK2INuF582Og==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", + "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/trace-mapping": "^0.2.2", - "sourcemap-codec": "1.4.8" + "@jridgewell/trace-mapping": "^0.3.0" }, "engines": { "node": ">=6.0.0" @@ -79,27 +77,27 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", - "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", + "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", "dependencies": { - "@ampproject/remapping": "^2.0.0", + "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.0", + "@babel/generator": "^7.17.7", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", @@ -153,9 +151,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", - "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", "dependencies": { "@babel/types": "^7.17.0", "jsesc": "^2.5.1", @@ -197,11 +195,11 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", "dependencies": { - "@babel/compat-data": "^7.16.4", + "@babel/compat-data": "^7.17.7", "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" @@ -383,18 +381,18 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", "dependencies": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -448,11 +446,11 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -511,12 +509,12 @@ } }, "node_modules/@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", + "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", "dependencies": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0" }, "engines": { @@ -566,9 +564,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/@babel/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1781,17 +1779,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", - "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", "dependencies": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", + "@babel/generator": "^7.17.3", "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-function-name": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.0", + "@babel/parser": "^7.17.3", "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" @@ -1843,16 +1841,16 @@ "dev": true }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -2457,20 +2455,25 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.3.tgz", - "integrity": "sha512-fuIOnc81C5iRNevb/XPiM8Khp9bVjreydRQ37rt0C/dY0PAW1DRvEM3WrKX/5rStS5lbgwS0FCgqSndh9tvK5w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", "engines": { - "node": ">=10.0.0" + "node": ">=6.0.0" } }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" + }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.2.2.tgz", - "integrity": "sha512-I9AGQzMPEzQNJgib2YSqciYWazGsXSyu1rEEeaPeM1764ZtnfNTxA5bofzG/POMI3QcvpBUxwecOPZM6ZhkEpg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", - "sourcemap-codec": "1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/@sindresorhus/is": { @@ -2667,12 +2670,12 @@ } }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" @@ -2778,9 +2781,9 @@ } }, "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "engines": { "node": ">=6" } @@ -3319,19 +3322,19 @@ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dependencies": { - "bytes": "3.1.1", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", + "qs": "6.9.7", + "raw-body": "2.4.3", "type-is": "~1.6.18" }, "engines": { @@ -3692,9 +3695,9 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } @@ -4012,9 +4015,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.1.tgz", - "integrity": "sha512-s6aac+DD+4O2u1aBmdxhB7yz2XU7tG3snOyQ05Kxifahz7hoxnfxIRHxiCSEv3TUC38dIVH8G+lZH9UWSfGQxA==" + "version": "5.65.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.2.tgz", + "integrity": "sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA==" }, "node_modules/collect-v8-coverage": { "version": "1.0.1", @@ -4956,12 +4959,12 @@ } }, "node_modules/eslint": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", - "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz", + "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -4969,10 +4972,10 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5008,9 +5011,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", - "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", + "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -5018,12 +5021,12 @@ "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", "object.hasown": "^1.1.0", "object.values": "^1.1.5", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", "string.prototype.matchall": "^4.0.6" @@ -5067,9 +5070,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -5107,9 +5110,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5175,15 +5178,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5212,14 +5206,14 @@ } }, "node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "dependencies": { "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5496,16 +5490,16 @@ } }, "node_modules/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dependencies": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.19.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -5520,7 +5514,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.9.7", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.17.2", @@ -5541,13 +5535,21 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "node_modules/express-static-gzip": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.3.tgz", - "integrity": "sha512-968gyrwqJXzBzx2gtmyBOj8hIlv/FpnvGM57AKWfaY4vqXHK7lsNQONSHeSdtat3+bhQ9db/sn4RPeoQigrzZA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.5.tgz", + "integrity": "sha512-bgiQ1fY7ltuUrSzg0WoN7ycoAd7r2VEw7durn/3k0jCMUC5wydF0K36ouIuJPE+MNDwK5uoSaVgIBVNemwxWgw==", "dependencies": { "serve-static": "^1.14.1" } }, + "node_modules/express/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5809,9 +5811,9 @@ } }, "node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5994,9 +5996,9 @@ } }, "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6054,9 +6056,9 @@ } }, "node_modules/googleapis": { - "version": "95.0.0", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-95.0.0.tgz", - "integrity": "sha512-ZpFZW7FDwcjQa2+xZNS2SC5sK2s46iWKA5QSFVJSK3RELQec4PYHhzKwzbeCzt4urnjYp6udPif95zXTFxbtRA==", + "version": "100.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-100.0.0.tgz", + "integrity": "sha512-RToFQGY54B756IDbjdyjb1vWFmn03bYpXHB2lIf0eq2UBYsIbYOLZ0kqSomfJnpclEukwEmMF7Jn6Wsev871ew==", "dependencies": { "google-auth-library": "^7.0.2", "googleapis-common": "^5.0.2" @@ -6497,9 +6499,9 @@ ] }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -8687,9 +8689,9 @@ } }, "node_modules/kareem": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.3.tgz", - "integrity": "sha512-uESCXM2KdtOQ8LOvKyTUXEeg0MkYp4wGglTIpGcYHvjJcS5sn2Wkfrfit8m4xSbaNDAw2KdI9elgkOxZbrFYbg==" + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" }, "node_modules/keyv": { "version": "3.1.0", @@ -9160,19 +9162,19 @@ } }, "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dependencies": { - "mime-db": "1.44.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -9206,9 +9208,9 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9217,9 +9219,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -9310,17 +9312,17 @@ } }, "node_modules/mongoose": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.1.tgz", - "integrity": "sha512-VxY1wvlc4uBQKyKNVDoEkTU3/ayFOD//qVXYP+sFyvTRbAj9/M53UWTERd84pWogs2TqAC6DTvZbxCs2LoOd3Q==", + "version": "6.2.9", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.9.tgz", + "integrity": "sha512-6ApgF3rKYah5pUEO/1H+QrT0GT05OR7FprtVM45yzcrT/IKKlXizPyttrMiK1mLPt+55pGU7PMsBWY7yx/xZ4g==", "dependencies": { "bson": "^4.2.2", - "kareem": "2.3.3", + "kareem": "2.3.5", "mongodb": "4.3.1", "mpath": "0.8.4", "mquery": "4.0.2", - "ms": "2.1.2", - "sift": "13.5.2" + "ms": "2.1.3", + "sift": "16.0.0" }, "engines": { "node": ">=12.0.0" @@ -9331,9 +9333,9 @@ } }, "node_modules/mongoose/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/mpath": { "version": "0.8.4", @@ -9387,9 +9389,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -9453,9 +9455,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } @@ -10055,9 +10057,9 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-platform": { "version": "0.11.15", @@ -10310,9 +10312,9 @@ } }, "node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "engines": { "node": ">=0.6" }, @@ -10379,11 +10381,11 @@ } }, "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dependencies": { - "bytes": "3.1.1", + "bytes": "3.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" @@ -11041,9 +11043,9 @@ } }, "node_modules/sift": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" }, "node_modules/signal-exit": { "version": "3.0.3", @@ -11307,11 +11309,6 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -13102,13 +13099,11 @@ }, "dependencies": { "@ampproject/remapping": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.0.1.tgz", - "integrity": "sha512-EldHF4Ufj3NL9yCAmYrPzY+3/Yqrzxu24F4Mu4nRjK3w70AKYRmhuLwGZdA9JeoDsbIwkgGkbqUK2INuF582Og==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", + "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/trace-mapping": "^0.2.2", - "sourcemap-codec": "1.4.8" + "@jridgewell/trace-mapping": "^0.3.0" } }, "@babel/code-frame": { @@ -13120,24 +13115,24 @@ } }, "@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==" + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==" }, "@babel/core": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", - "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", + "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", "requires": { - "@ampproject/remapping": "^2.0.0", + "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.0", + "@babel/generator": "^7.17.7", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", @@ -13175,9 +13170,9 @@ } }, "@babel/generator": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", - "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", "requires": { "@babel/types": "^7.17.0", "jsesc": "^2.5.1", @@ -13209,11 +13204,11 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", "requires": { - "@babel/compat-data": "^7.16.4", + "@babel/compat-data": "^7.17.7", "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" @@ -13343,18 +13338,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", "requires": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/helper-optimise-call-expression": { @@ -13393,11 +13388,11 @@ } }, "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -13438,12 +13433,12 @@ } }, "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", + "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", "requires": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", + "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0" } }, @@ -13483,9 +13478,9 @@ } }, "@babel/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==" + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.16.7", @@ -14280,17 +14275,17 @@ } }, "@babel/traverse": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", - "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", "requires": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", + "@babel/generator": "^7.17.3", "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-function-name": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.0", + "@babel/parser": "^7.17.3", "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" @@ -14332,16 +14327,16 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -14807,17 +14802,22 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.3.tgz", - "integrity": "sha512-fuIOnc81C5iRNevb/XPiM8Khp9bVjreydRQ37rt0C/dY0PAW1DRvEM3WrKX/5rStS5lbgwS0FCgqSndh9tvK5w==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" }, "@jridgewell/trace-mapping": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.2.2.tgz", - "integrity": "sha512-I9AGQzMPEzQNJgib2YSqciYWazGsXSyu1rEEeaPeM1764ZtnfNTxA5bofzG/POMI3QcvpBUxwecOPZM6ZhkEpg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", "requires": { "@jridgewell/resolve-uri": "^3.0.3", - "sourcemap-codec": "1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@sindresorhus/is": { @@ -15002,12 +15002,12 @@ } }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -15091,9 +15091,9 @@ }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==" }, "emoji-regex": { "version": "7.0.3", @@ -15516,19 +15516,19 @@ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "requires": { - "bytes": "3.1.1", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", + "qs": "6.9.7", + "raw-body": "2.4.3", "type-is": "~1.6.18" } }, @@ -15832,9 +15832,9 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, "cache-base": { "version": "1.0.1", @@ -16083,9 +16083,9 @@ "dev": true }, "codemirror": { - "version": "5.65.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.1.tgz", - "integrity": "sha512-s6aac+DD+4O2u1aBmdxhB7yz2XU7tG3snOyQ05Kxifahz7hoxnfxIRHxiCSEv3TUC38dIVH8G+lZH9UWSfGQxA==" + "version": "5.65.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.2.tgz", + "integrity": "sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA==" }, "collect-v8-coverage": { "version": "1.0.1", @@ -16859,12 +16859,12 @@ } }, "eslint": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", - "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz", + "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -16872,10 +16872,10 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -16941,12 +16941,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -16971,9 +16965,9 @@ } }, "eslint-plugin-react": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", - "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", + "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -16981,12 +16975,12 @@ "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", "object.hasown": "^1.1.0", "object.values": "^1.1.5", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", "string.prototype.matchall": "^4.0.6" @@ -17020,9 +17014,9 @@ } }, "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -17047,20 +17041,20 @@ } }, "eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "requires": { "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { "acorn": { @@ -17262,16 +17256,16 @@ } }, "express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.19.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -17286,7 +17280,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.9.7", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.17.2", @@ -17298,6 +17292,11 @@ "vary": "~1.1.2" }, "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -17311,9 +17310,9 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==" }, "express-static-gzip": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.3.tgz", - "integrity": "sha512-968gyrwqJXzBzx2gtmyBOj8hIlv/FpnvGM57AKWfaY4vqXHK7lsNQONSHeSdtat3+bhQ9db/sn4RPeoQigrzZA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.5.tgz", + "integrity": "sha512-bgiQ1fY7ltuUrSzg0WoN7ycoAd7r2VEw7durn/3k0jCMUC5wydF0K36ouIuJPE+MNDwK5uoSaVgIBVNemwxWgw==", "requires": { "serve-static": "^1.14.1" } @@ -17514,9 +17513,9 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -17650,9 +17649,9 @@ } }, "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -17691,9 +17690,9 @@ } }, "googleapis": { - "version": "95.0.0", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-95.0.0.tgz", - "integrity": "sha512-ZpFZW7FDwcjQa2+xZNS2SC5sK2s46iWKA5QSFVJSK3RELQec4PYHhzKwzbeCzt4urnjYp6udPif95zXTFxbtRA==", + "version": "100.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-100.0.0.tgz", + "integrity": "sha512-RToFQGY54B756IDbjdyjb1vWFmn03bYpXHB2lIf0eq2UBYsIbYOLZ0kqSomfJnpclEukwEmMF7Jn6Wsev871ew==", "requires": { "google-auth-library": "^7.0.2", "googleapis-common": "^5.0.2" @@ -18029,9 +18028,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "ignore-by-default": { @@ -19670,9 +19669,9 @@ "integrity": "sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==" }, "kareem": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.3.tgz", - "integrity": "sha512-uESCXM2KdtOQ8LOvKyTUXEeg0MkYp4wGglTIpGcYHvjJcS5sn2Wkfrfit8m4xSbaNDAw2KdI9elgkOxZbrFYbg==" + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" }, "keyv": { "version": "3.1.0", @@ -20041,16 +20040,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "requires": { - "mime-db": "1.44.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -20075,17 +20074,17 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mixin-deep": { "version": "1.3.2", @@ -20161,23 +20160,23 @@ } }, "mongoose": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.1.tgz", - "integrity": "sha512-VxY1wvlc4uBQKyKNVDoEkTU3/ayFOD//qVXYP+sFyvTRbAj9/M53UWTERd84pWogs2TqAC6DTvZbxCs2LoOd3Q==", + "version": "6.2.9", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.9.tgz", + "integrity": "sha512-6ApgF3rKYah5pUEO/1H+QrT0GT05OR7FprtVM45yzcrT/IKKlXizPyttrMiK1mLPt+55pGU7PMsBWY7yx/xZ4g==", "requires": { "bson": "^4.2.2", - "kareem": "2.3.3", + "kareem": "2.3.5", "mongodb": "4.3.1", "mpath": "0.8.4", "mquery": "4.0.2", - "ms": "2.1.2", - "sift": "13.5.2" + "ms": "2.1.3", + "sift": "16.0.0" }, "dependencies": { "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -20221,9 +20220,9 @@ "optional": true }, "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" }, "nanomatch": { "version": "1.2.13", @@ -20274,9 +20273,9 @@ } }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "node-fetch": { "version": "2.6.7", @@ -20729,9 +20728,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-platform": { "version": "0.11.15", @@ -20936,9 +20935,9 @@ } }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" }, "query-string": { "version": "7.1.1", @@ -20984,11 +20983,11 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "requires": { - "bytes": "3.1.1", + "bytes": "3.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" @@ -21533,9 +21532,9 @@ } }, "sift": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" }, "signal-exit": { "version": "3.0.3", @@ -21736,11 +21735,6 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", diff --git a/package.json b/package.json index 3ab8c7b3a..45bc3fdb1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "homebrewery", "description": "Create authentic looking D&D homebrews using only markdown", - "version": "3.0.7", + "version": "3.0.8", "engines": { "node": "16.11.x" }, @@ -20,6 +20,9 @@ "verify": "npm run lint && npm test", "test": "jest", "test:dev": "jest --verbose --watch", + "test:basic": "jest tests/markdown/basic.test.js --verbose", + "test:mustache-span": "jest tests/markdown/mustache-span.test.js --verbose", + "test:route": "jest tests/routes/static-pages.test.js --verbose", "phb": "node scripts/phb.js", "prod": "set NODE_ENV=production && npm run build", "postinstall": "npm run buildall", @@ -31,6 +34,7 @@ "build/*" ], "jest": { + "testTimeout" : 15000, "modulePaths": [ "mode_modules", "shared", @@ -47,21 +51,21 @@ ] }, "dependencies": { - "@babel/core": "^7.17.2", + "@babel/core": "^7.17.8", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", - "body-parser": "^1.19.1", + "body-parser": "^1.19.2", "classnames": "^2.3.1", - "codemirror": "^5.65.1", + "codemirror": "^5.65.2", "cookie-parser": "^1.4.6", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.1", - "express": "^4.17.2", + "express": "^4.17.3", "express-async-handler": "^1.2.0", - "express-static-gzip": "2.1.3", - "fs-extra": "10.0.0", - "googleapis": "95.0.0", + "express-static-gzip": "2.1.5", + "fs-extra": "10.0.1", + "googleapis": "100.0.0", "js-yaml": "^4.1.0", "jwt-simple": "^0.5.6", "less": "^3.13.1", @@ -70,8 +74,8 @@ "marked-extended-tables": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.29.1", - "mongoose": "^6.2.1", - "nanoid": "3.2.0", + "mongoose": "^6.2.9", + "nanoid": "3.3.2", "nconf": "^0.11.3", "query-string": "7.1.1", "react": "^16.14.0", @@ -83,8 +87,8 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "eslint": "^8.8.0", - "eslint-plugin-react": "^7.28.0", + "eslint": "^8.12.0", + "eslint-plugin-react": "^7.29.4", "jest": "^27.5.1", "supertest": "^6.2.2" } diff --git a/server/app.js b/server/app.js index 3ea043d37..135e0a8be 100644 --- a/server/app.js +++ b/server/app.js @@ -25,7 +25,7 @@ const getBrewFromId = asyncHandler(async (id, accessType)=>{ if(id.length > 12) { const googleId = id.slice(0, -12); id = id.slice(-12); - brew = await GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, id, accessType); + brew = await GoogleActions.getGoogleBrew(googleId, id, accessType); } else { brew = await HomebrewModel.get(accessType == 'edit' ? { editId: id } : { shareId: id }); brew = brew.toObject(); // Convert MongoDB object to standard Javascript Object @@ -201,13 +201,16 @@ app.get('/user/:username', async (req, res, next)=>{ }); if(ownAccount && req?.account?.googleId){ - const googleBrews = await GoogleActions.listGoogleBrews(req, res) - .catch((err)=>{ - console.error(err); - }); + const auth = await GoogleActions.authCheck(req.account, res); + let googleBrews = await GoogleActions.listGoogleBrews(auth) + .catch((err)=>{ + console.error(err); + }); - if(googleBrews) + if(googleBrews) { + googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); brews = _.concat(brews, googleBrews); + } } req.brews = _.map(brews, (brew)=>{ diff --git a/server/googleActions.js b/server/googleActions.js index 9d17abdce..3a202cbce 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -5,7 +5,20 @@ const { nanoid } = require('nanoid'); const token = require('./token.js'); const config = require('./config.js'); -//let oAuth2Client; +const keys = typeof(config.get('service_account')) == 'string' ? + JSON.parse(config.get('service_account')) : + config.get('service_account'); +let serviceAuth; +try { + serviceAuth = google.auth.fromJSON(keys); + serviceAuth.scopes = [ + 'https://www.googleapis.com/auth/drive' + ]; +} catch (err) { + console.warn(err); + console.log('Please make sure that a Google Service Account is set up properly in your config files.'); +} +google.options({ auth: serviceAuth || config.get('google_api_key') }); const GoogleActions = { @@ -43,7 +56,7 @@ const GoogleActions = { }, getGoogleFolder : async (auth)=>{ - const drive = google.drive({ version: 'v3', auth: auth }); + const drive = google.drive({ version: 'v3', auth }); fileMetadata = { 'name' : 'Homebrewery', @@ -79,17 +92,8 @@ const GoogleActions = { return folderId; }, - listGoogleBrews : async (req, res)=>{ - - oAuth2Client = GoogleActions.authCheck(req.account, res); - - //TODO: Change to service account to allow non-owners to view published files. - // Requires a driveId parameter in the drive.files.list command - // const keys = JSON.parse(config.get('service_account')); - // const auth = google.auth.fromJSON(keys); - // auth.scopes = ['https://www.googleapis.com/auth/drive']; - - const drive = google.drive({ version: 'v3', auth: oAuth2Client }); + listGoogleBrews : async (auth)=>{ + const drive = google.drive({ version: 'v3', auth }); const obj = await drive.files.list({ pageSize : 1000, @@ -97,18 +101,18 @@ const GoogleActions = { q : 'mimeType != \'application/vnd.google-apps.folder\' and trashed = false' }) .catch((err)=>{ - console.log(`Error Listing Google Brews`); + console.log(`Error Listing Google Brews`); console.error(err); throw (err); //TODO: Should break out here, but continues on for some reason. - }); + }); if(!obj.data.files.length) { - console.log('No files found.'); - } + console.log('No files found.'); + } const brews = obj.data.files.map((file)=>{ - return { + return { text : '', shareId : file.properties.shareId, editId : file.properties.editId, @@ -122,65 +126,47 @@ const GoogleActions = { views : parseInt(file.properties.views), tags : '', published : file.properties.published ? file.properties.published == 'true' : false, - authors : [req.account.username], //TODO: properly save and load authors to google drive systems : [] }; }); return brews; }, - existsGoogleBrew : async (auth, id)=>{ - const drive = google.drive({ version: 'v3', auth: auth }); + updateGoogleBrew : async (brew)=>{ + const drive = google.drive({ version: 'v3' }); - const result = await drive.files.get({ fileId: id }) - .catch((err)=>{ - console.log('error checking file exists...'); - console.error(err); - return false; - }); - - if(result){return true;} - - return false; - }, - - updateGoogleBrew : async (auth, brew)=>{ - const drive = google.drive({ version: 'v3', auth: auth }); - - if(await GoogleActions.existsGoogleBrew(auth, brew.googleId) == true) { - await drive.files.update({ - fileId : brew.googleId, - resource : { - name : `${brew.title}.txt`, - description : `${brew.description}`, - properties : { - title : brew.title, - published : brew.published, - version : brew.version, - renderer : brew.renderer, - tags : brew.tags, - pageCount : brew.pageCount, - systems : brew.systems.join() - } - }, - media : { - mimeType : 'text/plain', - body : brew.text + await drive.files.update({ + fileId : brew.googleId, + resource : { + name : `${brew.title}.txt`, + description : `${brew.description}`, + properties : { + title : brew.title, + published : brew.published, + version : brew.version, + renderer : brew.renderer, + tags : brew.tags, + pageCount : brew.pageCount, + systems : brew.systems.join() } - }) - .catch((err)=>{ - console.log('Error saving to google'); - console.error(err); - throw (err); - //return res.status(500).send('Error while saving'); - }); - } + }, + media : { + mimeType : 'text/plain', + body : brew.text + } + }) + .catch((err)=>{ + console.log('Error saving to google'); + console.error(err); + throw (err); + //return res.status(500).send('Error while saving'); + }); return (brew); }, newGoogleBrew : async (auth, brew)=>{ - const drive = google.drive({ version: 'v3', auth: auth }); + const drive = google.drive({ version: 'v3', auth }); const media = { mimeType : 'text/plain', @@ -194,8 +180,8 @@ const GoogleActions = { 'description' : `${brew.description}`, 'parents' : [folderId], 'properties' : { //AppProperties is not accessible - 'shareId' : nanoid(12), - 'editId' : nanoid(12), + 'shareId' : brew.shareId || nanoid(12), + 'editId' : brew.editId || nanoid(12), 'title' : brew.title, 'views' : '0', 'pageCount' : brew.pageCount, @@ -248,9 +234,8 @@ const GoogleActions = { return newHomebrew; }, - readFileMetadata : async (auth, id, accessId, accessType)=>{ - - const drive = google.drive({ version: 'v3', auth: auth }); + getGoogleBrew : async (id, accessId, accessType)=>{ + const drive = google.drive({ version: 'v3' }); const obj = await drive.files.get({ fileId : id, @@ -269,16 +254,7 @@ const GoogleActions = { throw ('Share ID does not match'); } - //Access file using service account. Using API key only causes "automated query" lockouts after a while. - - const keys = typeof(config.get('service_account')) == 'string' ? - JSON.parse(config.get('service_account')) : - config.get('service_account'); - - const serviceAuth = google.auth.fromJSON(keys); - serviceAuth.scopes = ['https://www.googleapis.com/auth/drive']; - - const serviceDrive = google.drive({ version: 'v3', auth: serviceAuth }); + const serviceDrive = google.drive({ version: 'v3' }); const file = await serviceDrive.files.get({ fileId : id, @@ -319,10 +295,8 @@ const GoogleActions = { } }, - deleteGoogleBrew : async (req, res, id)=>{ - - oAuth2Client = GoogleActions.authCheck(req.account, res); - const drive = google.drive({ version: 'v3', auth: oAuth2Client }); + deleteGoogleBrew : async (auth, id)=>{ + const drive = google.drive({ version: 'v3', auth }); const googleId = id.slice(0, -12); const accessId = id.slice(-12); @@ -334,7 +308,6 @@ const GoogleActions = { .catch((err)=>{ console.log('Error loading from Google'); console.error(err); - return; }); if(obj && obj.data.properties.editId != accessId) { @@ -349,21 +322,10 @@ const GoogleActions = { console.log('Can\'t delete Google file'); console.error(err); }); - - return res.status(200).send(); }, increaseView : async (id, accessId, accessType, brew)=>{ - //service account because this is modifying another user's file properties - //so we need extended scope - const keys = typeof(config.get('service_account')) == 'string' ? - JSON.parse(config.get('service_account')) : - config.get('service_account'); - - const auth = google.auth.fromJSON(keys); - auth.scopes = ['https://www.googleapis.com/auth/drive']; - - const drive = google.drive({ version: 'v3', auth: auth }); + const drive = google.drive({ version: 'v3' }); await drive.files.update({ fileId : brew.googleId, @@ -380,8 +342,6 @@ const GoogleActions = { console.error(err); //return res.status(500).send('Error while saving'); }); - - return; } }; diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 94e295d30..3c1267f0b 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -5,6 +5,7 @@ const zlib = require('zlib'); const GoogleActions = require('./googleActions.js'); const Markdown = require('../shared/naturalcrit/markdown.js'); const yaml = require('js-yaml'); +const asyncHandler = require('express-async-handler'); // const getTopBrews = (cb) => { // HomebrewModel.find().sort({ views: -1 }).limit(5).exec(function(err, brews) { @@ -41,154 +42,195 @@ const excludePropsFromUpdate = (brew)=>{ const propsToExclude = ['views', 'lastViewed']; for (const prop of propsToExclude) { delete brew[prop]; - }; + } return brew; }; -const newBrew = (req, res)=>{ - const brew = req.body; - +const beforeNewSave = (account, brew)=>{ if(!brew.title) { brew.title = getGoodBrewTitle(brew.text); } - brew.authors = (req.account) ? [req.account.username] : []; + brew.authors = (account) ? [account.username] : []; brew.text = mergeBrewText(brew); +}; - delete brew.editId; - delete brew.shareId; - delete brew.googleId; - +const newLocalBrew = async (brew)=>{ const newHomebrew = new HomebrewModel(brew); // Compress brew text to binary before saving newHomebrew.textBin = zlib.deflateRawSync(newHomebrew.text); // Delete the non-binary text field since it's not needed anymore newHomebrew.text = undefined; - newHomebrew.save((err, obj)=>{ - if(err) { - console.error(err, err.toString(), err.stack); - return res.status(500).send(`Error while creating new brew, ${err.toString()}`); - } - - obj = obj.toObject(); - obj.gDrive = false; - return res.status(200).send(obj); - }); -}; - -const updateBrew = (req, res)=>{ - HomebrewModel.get({ editId: req.params.id }) - .then((brew)=>{ - const updateBrew = excludePropsFromUpdate(req.body); - brew = _.merge(brew, updateBrew); - brew.text = mergeBrewText(brew); - - // Compress brew text to binary before saving - brew.textBin = zlib.deflateRawSync(brew.text); - // Delete the non-binary text field since it's not needed anymore - brew.text = undefined; - brew.updatedAt = new Date(); - - if(req.account) { - brew.authors = _.uniq(_.concat(brew.authors, req.account.username)); - } - - brew.markModified('authors'); - brew.markModified('systems'); - - brew.save((err, obj)=>{ - if(err) throw err; - return res.status(200).send(obj); - }); - }) + let saved = await newHomebrew.save() .catch((err)=>{ - console.error(err); - return res.status(500).send('Error while saving'); + console.error(err, err.toString(), err.stack); + throw `Error while creating new brew, ${err.toString()}`; }); + + saved = saved.toObject(); + saved.gDrive = false; + return saved; }; -const deleteBrew = (req, res)=>{ - HomebrewModel.find({ editId: req.params.id }, (err, objs)=>{ - if(!objs.length || err) { - return res.status(404).send('Can not find homebrew with that id'); - } +const newGoogleBrew = async (account, brew, res)=>{ + const oAuth2Client = GoogleActions.authCheck(account, res); - const brew = objs[0]; - - if(req.account) { - // Remove current user as author - brew.authors = _.pull(brew.authors, req.account.username); - brew.markModified('authors'); - } - - if(brew.authors.length === 0) { - // Delete brew if there are no authors left - brew.remove((err)=>{ - if(err) return res.status(500).send('Error while removing'); - return res.status(200).send(); - }); - } else { - // Otherwise, save the brew with updated author list - brew.save((err, savedBrew)=>{ - if(err) throw err; - return res.status(200).send(savedBrew); - }); - } - }); + return await GoogleActions.newGoogleBrew(oAuth2Client, brew); }; -const newGoogleBrew = async (req, res, next)=>{ - let oAuth2Client; - - try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); } - +const newBrew = async (req, res)=>{ const brew = req.body; - - if(!brew.title) { - brew.title = getGoodBrewTitle(brew.text); - } - - brew.authors = (req.account) ? [req.account.username] : []; - brew.text = mergeBrewText(brew); + const { transferToGoogle } = req.query; delete brew.editId; delete brew.shareId; delete brew.googleId; - req.body = brew; + beforeNewSave(req.account, brew); - try { - const newBrew = await GoogleActions.newGoogleBrew(oAuth2Client, brew); - return res.status(200).send(newBrew); - } catch (err) { - return res.status(err.response.status).send(err); + let saved; + if(transferToGoogle) { + saved = await newGoogleBrew(req.account, brew, res) + .catch((err)=>{ + res.status(err.status || err.response.status).send(err.message || err); + }); + } else { + saved = await newLocalBrew(brew) + .catch((err)=>{ + res.status(500).send(err); + }); + } + if(!saved) return; + return res.status(200).send(saved); +}; + +const updateBrew = async (req, res)=>{ + let brew = excludePropsFromUpdate(req.body); + const { transferToGoogle, transferFromGoogle } = req.query; + + let saved; + if(brew.googleId && transferFromGoogle) { + beforeNewSave(req.account, brew); + + saved = await newLocalBrew(brew) + .catch((err)=>{ + console.error(err); + res.status(500).send(err); + }); + if(!saved) return; + + await deleteGoogleBrew(req.account, `${brew.googleId}${brew.editId}`, res) + .catch((err)=>{ + console.error(err); + res.status(err.status || err.response.status).send(err.message || err); + }); + } else if(!brew.googleId && transferToGoogle) { + saved = await newGoogleBrew(req.account, brew, res) + .catch((err)=>{ + console.error(err); + res.status(err.status || err.response.status).send(err.message || err); + }); + if(!saved) return; + + await deleteLocalBrew(req.account, brew.editId) + .catch((err)=>{ + console.error(err); + res.status(err.status).send(err.message); + }); + } else if(brew.googleId) { + brew.text = mergeBrewText(brew); + + saved = await GoogleActions.updateGoogleBrew(brew) + .catch((err)=>{ + console.error(err); + res.status(err.response?.status || 500).send(err); + }); + } else { + const dbBrew = await HomebrewModel.get({ editId: req.params.id }) + .catch((err)=>{ + console.error(err); + return res.status(500).send('Error while saving'); + }); + + brew = _.merge(dbBrew, brew); + brew.text = mergeBrewText(brew); + + // Compress brew text to binary before saving + brew.textBin = zlib.deflateRawSync(brew.text); + // Delete the non-binary text field since it's not needed anymore + brew.text = undefined; + brew.updatedAt = new Date(); + + if(req.account) { + brew.authors = _.uniq(_.concat(brew.authors, req.account.username)); + } + + brew.markModified('authors'); + brew.markModified('systems'); + + saved = await brew.save(); + } + if(!saved) return; + + if(!res.headersSent) return res.status(200).send(saved); +}; + +const deleteBrew = async (req, res)=>{ + if(req.params.id.length > 12) { + const deleted = await deleteGoogleBrew(req.account, req.params.id, res) + .catch((err)=>{ + res.status(500).send(err); + }); + if(deleted) return res.status(200).send(); + } else { + const deleted = await deleteLocalBrew(req.account, req.params.id) + .catch((err)=>{ + res.status(err.status).send(err.message); + }); + if(deleted) return res.status(200).send(deleted); + return res.status(200).send(); } }; -const updateGoogleBrew = async (req, res, next)=>{ - let oAuth2Client; +const deleteLocalBrew = async (account, id)=>{ + const brew = await HomebrewModel.findOne({ editId: id }); + if(!brew) { + throw { status: 404, message: 'Can not find homebrew with that id' }; + } - try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); } + if(account) { + // Remove current user as author + brew.authors = _.pull(brew.authors, account.username); + brew.markModified('authors'); + } - const brew = excludePropsFromUpdate(req.body); - brew.text = mergeBrewText(brew); - - try { - const updatedBrew = await GoogleActions.updateGoogleBrew(oAuth2Client, brew); - return res.status(200).send(updatedBrew); - } catch (err) { - return res.status(err.response?.status || 500).send(err); + if(brew.authors.length === 0) { + // Delete brew if there are no authors left + await brew.remove() + .catch((err)=>{ + console.error(err); + throw { status: 500, message: 'Error while removing' }; + }); + } else { + // Otherwise, save the brew with updated author list + return await brew.save() + .catch((err)=>{ + throw { status: 500, message: err }; + }); } }; -router.post('/api', newBrew); -router.post('/api/newGoogle/', newGoogleBrew); -router.put('/api/:id', updateBrew); -router.put('/api/update/:id', updateBrew); -router.put('/api/updateGoogle/:id', updateGoogleBrew); -router.delete('/api/:id', deleteBrew); -router.get('/api/remove/:id', deleteBrew); -router.get('/api/removeGoogle/:id', (req, res)=>{GoogleActions.deleteGoogleBrew(req, res, req.params.id);}); +const deleteGoogleBrew = async (account, id, res)=>{ + const auth = await GoogleActions.authCheck(account, res); + await GoogleActions.deleteGoogleBrew(auth, id); + return true; +}; + +router.post('/api', asyncHandler(newBrew)); +router.put('/api/:id', asyncHandler(updateBrew)); +router.put('/api/update/:id', asyncHandler(updateBrew)); +router.delete('/api/:id', asyncHandler(deleteBrew)); +router.get('/api/remove/:id', asyncHandler(deleteBrew)); module.exports = router; diff --git a/shared/naturalcrit/splitPane/splitPane.jsx b/shared/naturalcrit/splitPane/splitPane.jsx index 1b4cee5ae..4d138e30b 100644 --- a/shared/naturalcrit/splitPane/splitPane.jsx +++ b/shared/naturalcrit/splitPane/splitPane.jsx @@ -10,43 +10,69 @@ const SplitPane = createClass({ return { storageKey : 'naturalcrit-pane-split', onDragFinish : function(){} //fires when dragging - }; }, + getInitialState : function() { return { - size : null, - isDragging : false + currentDividerPos : null, + windowWidth : 0, + isDragging : false }; }, + componentDidMount : function() { - const paneSize = window.localStorage.getItem(this.props.storageKey); - if(paneSize){ + const dividerPos = window.localStorage.getItem(this.props.storageKey); + if(dividerPos){ this.setState({ - size : paneSize + currentDividerPos : this.limitPosition(dividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13)), + userSetDividerPos : dividerPos, + windowWidth : window.innerWidth }); } + window.addEventListener('resize', this.handleWindowResize); + }, + + componentWillUnmount : function() { + window.removeEventListener('resize', this.handleWindowResize); + }, + + handleWindowResize : function() { + // Allow divider to increase in size to last user-set position + // Limit current position to between 10% and 90% of visible space + const newLoc = this.limitPosition(this.state.userSetDividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13)); + + this.setState({ + currentDividerPos : newLoc, + windowWidth : window.innerWidth + }); + }, + + limitPosition : function(x, min = 1, max = window.innerWidth - 13) { + const result = Math.round(Math.min(max, Math.max(min, x))); + return result; }, handleUp : function(){ if(this.state.isDragging){ - this.props.onDragFinish(this.state.size); - window.localStorage.setItem(this.props.storageKey, this.state.size); + this.props.onDragFinish(this.state.currentDividerPos); + window.localStorage.setItem(this.props.storageKey, this.state.currentDividerPos); } this.setState({ isDragging: false }); }, + handleDown : function(){ this.setState({ isDragging: true }); //this.unFocus() }, + handleMove : function(e){ if(!this.state.isDragging) return; - const minWidth = 1; - const maxWidth = window.innerWidth - 13; - const newSize = Math.min(maxWidth, Math.max(minWidth, e.pageX)); + const newSize = this.limitPosition(e.pageX); this.setState({ - size : newSize + currentDividerPos : newSize, + userSetDividerPos : newSize }); }, /* @@ -70,7 +96,7 @@ const SplitPane = createClass({ render : function(){ return
- {this.props.children[0]} + {this.props.children[0]} {this.renderDivider()} {this.props.children[1]}
; diff --git a/themes/V3/5eDMG/snippets.js b/themes/V3/5eDMG/snippets.js index 727e17359..cd0911c1b 100644 --- a/themes/V3/5eDMG/snippets.js +++ b/themes/V3/5eDMG/snippets.js @@ -98,7 +98,11 @@ module.exports = [ gen : dedent`/* Removes Drop Caps */ .page h1+p:first-letter { all: unset; - }\n\n` + }\n\n + /* Removes Small-Caps in first line */ + .page h1+p:first-line { + all: unset; + }` }, { name : 'Tweak Drop Cap', diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index 63af5e972..0ca89693b 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -621,6 +621,8 @@ body { } &.decoration { transform-style : preserve-3d; + z-index: -1; + position:relative; } &.decoration::before { content :''; @@ -656,7 +658,7 @@ body { margin-bottom : 0.3cm; } a{ - display : table; + display : inline; color : inherit; text-decoration : none; &:hover{