From e06fb95d9eb533a8d7d3897a71f533fb52998dcf Mon Sep 17 00:00:00 2001 From: Andy Nicholson <intothemist@gmail.com> Date: Tue, 19 Jan 2021 16:48:28 +1100 Subject: [PATCH] feat(*): published manuscripts interface enhancements --- app/app.js | 3 +- app/components/AdminPage.js | 33 +- .../component-frontpage/src/Frontpage.js | 168 +++++----- .../src/ManuscriptDetails.js | 4 +- .../component-frontpage/src/queries.js | 18 +- app/components/component-login/src/Login.jsx | 2 + .../src/components/ManuscriptPage.js | 3 + .../component-manuscripts/src/Manuscripts.jsx | 3 +- .../src/components/metadata/ReviewMetadata.js | 12 +- app/components/component-submit/src/upload.js | 8 + app/components/xpub-journal/src/index.js | 14 +- package.json | 13 +- server/app.js | 25 +- .../src/reviewBackend.js | 20 ++ yarn.lock | 299 ++++++++++++++++-- 15 files changed, 473 insertions(+), 152 deletions(-) diff --git a/app/app.js b/app/app.js index 3416289a67..f67147deda 100644 --- a/app/app.js +++ b/app/app.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-extraneous-dependencies */ import 'regenerator-runtime/runtime' import React from 'react' import ReactDOM from 'react-dom' @@ -12,8 +13,6 @@ import { XpubProvider } from './components/xpub-with-context/src' import * as journal from '../config/journal' import routes from './routes' - - const history = createBrowserHistory() const rootEl = document.getElementById('root') diff --git a/app/components/AdminPage.js b/app/components/AdminPage.js index 19c02ee7cc..1f1151738b 100644 --- a/app/components/AdminPage.js +++ b/app/components/AdminPage.js @@ -11,17 +11,17 @@ import { import { JournalContext } from './xpub-journal/src' import { XpubContext } from './xpub-with-context/src' -import UsersManager from '../components/component-users-manager/src/UsersManager' -import Manuscripts from '../components/component-manuscripts/src/Manuscripts' -import Dashboard from '../components/component-dashboard/src/components/Dashboard' -import SubmitPage from '../components/component-submit/src/components/SubmitPage' -import ManuscriptPage from '../components/component-manuscript/src/components/ManuscriptPage' -import ReviewersPage from '../components/component-review/src/components/ReviewersPage' -import ReviewPage from '../components/component-review/src/components/ReviewPage' -import DecisionPage from '../components/component-review/src/components/DecisionPage' -import FormBuilderPage from '../components/component-formbuilder/src/components/FormBuilderPage' -import NewSubmissionPage from '../components/component-submit/src/components/NewSubmissionPage' -import { Profile } from '../components/component-profile/src' +import UsersManager from './component-users-manager/src/UsersManager' +import Manuscripts from './component-manuscripts/src/Manuscripts' +import Dashboard from './component-dashboard/src/components/Dashboard' +import SubmitPage from './component-submit/src/components/SubmitPage' +import ManuscriptPage from './component-manuscript/src/components/ManuscriptPage' +import ReviewersPage from './component-review/src/components/ReviewersPage' +import ReviewPage from './component-review/src/components/ReviewPage' +import DecisionPage from './component-review/src/components/DecisionPage' +import FormBuilderPage from './component-formbuilder/src/components/FormBuilderPage' +import NewSubmissionPage from './component-submit/src/components/NewSubmissionPage' +import { Profile } from './component-profile/src' import { GET_CURRENT_USER } from '../queries' @@ -38,11 +38,10 @@ const getParams = routerPath => { const Root = styled.div` display: grid; - grid-template-columns: 200px auto; grid-template-areas: 'menu main'; - max-height: 100vh; + grid-template-columns: 200px auto; height: 100vh; - overflow: hidden; + max-height: 100vh; ${({ converting }) => converting && ` @@ -51,9 +50,11 @@ const Root = styled.div` pointer-events: none; } `}; + overflow: hidden; ` // TODO: Redirect if token expires +// eslint-disable-next-line react/prop-types const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} @@ -67,8 +68,10 @@ const PrivateRoute = ({ component: Component, ...rest }) => ( /> ) +// eslint-disable-next-line consistent-return const updateStuff = data => { if (data?.currentUser) { + // eslint-disable-next-line no-underscore-dangle return currentRolesVar(data.currentUser._currentRoles) } } @@ -81,6 +84,7 @@ const AdminPage = () => { const { loading, error, data } = useQuery(GET_CURRENT_USER, { fetchPolicy: 'network-only', // TODO: useCallback used because of bug: https://github.com/apollographql/apollo-client/issues/6301 + // eslint-disable-next-line no-shadow onCompleted: useCallback(data => updateStuff(data), []), }) @@ -92,6 +96,7 @@ const AdminPage = () => { } let notice = '' + if (error) { if (error.networkError) { notice = 'You are offline.' diff --git a/app/components/component-frontpage/src/Frontpage.js b/app/components/component-frontpage/src/Frontpage.js index ff48860f1b..a3daede1e2 100644 --- a/app/components/component-frontpage/src/Frontpage.js +++ b/app/components/component-frontpage/src/Frontpage.js @@ -3,7 +3,6 @@ import { useQuery } from '@apollo/client' import { JournalContext } from '../../xpub-journal/src' import queries from './queries' import { Container, Placeholder, VisualAbstract } from './style' -import Wax from '../../wax-collab/src/Editoria' import { Spinner, @@ -16,21 +15,23 @@ import { Pagination, } from '../../shared' +import { UserAction as Action } from '../../component-manuscripts/src/style' +// eslint-disable-next-line react/prop-types const Frontpage = ({ history, ...props }) => { - + // eslint-disable-next-line no-unused-vars const [sortName, setSortName] = useState('created') + // eslint-disable-next-line no-unused-vars const [sortDirection, setSortDirection] = useState('DESC') const [page, setPage] = useState(1) - const limit = 2 + const limit = 10 const sort = sortName && sortDirection && `${sortName}_${sortDirection}` - - const skipXSweet = file => - !( - file.mimeType === - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' - ) + const skipXSweet = file => + !( + file.mimeType === + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ) const { loading, data, error } = useQuery(queries.frontpage, { variables: { @@ -40,15 +41,15 @@ const Frontpage = ({ history, ...props }) => { }, fetchPolicy: 'network-only', }) - + const journal = useContext(JournalContext) if (loading) return <Spinner /> if (error) return JSON.stringify(error) - const totalCount = data.publishedManuscripts.totalCount + const { totalCount } = data.publishedManuscripts - const frontpage = (data.publishedManuscripts?.manuscripts || []).map(m => { + const frontpage = (data.publishedManuscripts?.manuscripts || []).map(m => { const visualAbstract = m.files?.find(f => f.fileType === 'visualAbstract') return { ...m, @@ -57,86 +58,96 @@ const Frontpage = ({ history, ...props }) => { } }) - - return ( <Container> <HeadingWithAction> <Heading>Recent publications in {journal.metadata.name}</Heading> </HeadingWithAction> <Pagination - limit={limit} - page={page} - setPage={setPage} - totalCount={totalCount} - /> + limit={limit} + page={page} + setPage={setPage} + totalCount={totalCount} + /> {frontpage.length > 0 ? ( frontpage.map(manuscript => ( + // eslint-disable-next-line react/jsx-key <SectionContent> <SectionHeader> <Title>{manuscript.meta.title}</Title> </SectionHeader> <SectionRow key={`manuscript-${manuscript.id}`}> - - {manuscript.submission?.abstract ? - <p>Abstract: {manuscript.submission?.abstract}</p> - : <br/> } - {manuscript.visualAbstract ? - <p> - Visual abstract:{' '} - <VisualAbstract - alt="Visual abstract" - src={manuscript.visualAbstract} - /> - </p> : <br/> } - - {manuscript.files.length > 0 ? - - <div> - {manuscript.files.map(file => ( - skipXSweet(file) && - <p> - <a - href={file.url} - rel="noopener noreferrer" - target="_blank" - > - {file.filename} - </a> - </p> - ))} - {manuscript.files.map(file => ( - (! skipXSweet(file)) && - - <p> - <Wax - content={manuscript.meta.source} - readonly - /> - </p> - - ))} - - - </div> : <br/> } - - {manuscript.submission?.links ? - <div> - Submitted research objects: - {manuscript.submission?.links?.map(link => ( - <p> - <a - href={link.url} - rel="noopener noreferrer" - target="_blank" - > - {link.url} - </a> - </p> - ))} - </div> : <br/> } - + {manuscript.submission?.abstract ? ( + <p>Abstract: {manuscript.submission?.abstract}</p> + ) : ( + <br /> + )} + {manuscript.visualAbstract ? ( + <p> + Visual abstract:{' '} + <VisualAbstract + alt="Visual abstract" + src={manuscript.visualAbstract} + /> + </p> + ) : ( + <br /> + )} + + {manuscript.files.length > 0 ? ( + <div> + {manuscript.files.map( + file => + skipXSweet(file) && + file.fileType !== 'visualAbstract' && ( + <p> + <a + href={file.url} + rel="noopener noreferrer" + target="_blank" + > + {file.filename} + </a> + </p> + ), + )} + {manuscript.files.map( + file => + !skipXSweet(file) && ( + <p> + <Action + to={`/journal/versions/${manuscript.id}/manuscript`} + > + View Manuscript Text + </Action> + </p> + ), + )} + </div> + ) : ( + <br /> + )} + + {manuscript.submission?.links ? ( + <div> + Submitted research objects: + {manuscript.submission?.links?.map(link => ( + // eslint-disable-next-line react/jsx-key + <p> + <a + href={link.url} + rel="noopener noreferrer" + target="_blank" + > + {link.url} + </a> + </p> + ))} + </div> + ) : ( + <br /> + )} </SectionRow> </SectionContent> )) @@ -146,4 +157,5 @@ const Frontpage = ({ history, ...props }) => { </Container> ) } + export default Frontpage diff --git a/app/components/component-frontpage/src/ManuscriptDetails.js b/app/components/component-frontpage/src/ManuscriptDetails.js index 6b5bfdab4e..1bbcc7c544 100644 --- a/app/components/component-frontpage/src/ManuscriptDetails.js +++ b/app/components/component-frontpage/src/ManuscriptDetails.js @@ -1,5 +1,7 @@ import React from 'react' -const ManuscriptDetails = () => <div>Nothing here yet.</div> +const ManuscriptDetails = () => ( + <div>Nothing here yet in ManuscriptDetails.</div> +) export default ManuscriptDetails diff --git a/app/components/component-frontpage/src/queries.js b/app/components/component-frontpage/src/queries.js index 3e60696493..effb23f6e8 100644 --- a/app/components/component-frontpage/src/queries.js +++ b/app/components/component-frontpage/src/queries.js @@ -1,18 +1,10 @@ +// eslint-disable-next-line import/no-extraneous-dependencies import gql from 'graphql-tag' export default { frontpage: gql` - - query publishedManuscripts( - $sort: String - $offset: Int - $limit: Int - ) { - publishedManuscripts( - sort: $sort - offset: $offset - limit: $limit - ) { + query publishedManuscripts($sort: String, $offset: Int, $limit: Int) { + publishedManuscripts(sort: $sort, offset: $offset, limit: $limit) { totalCount manuscripts { id @@ -36,14 +28,14 @@ export default { url filename fileType - mimeType + mimeType } meta { manuscriptId title articleSections articleType - source + source history { type date diff --git a/app/components/component-login/src/Login.jsx b/app/components/component-login/src/Login.jsx index d04d53a279..b3a8a330ce 100644 --- a/app/components/component-login/src/Login.jsx +++ b/app/components/component-login/src/Login.jsx @@ -19,9 +19,11 @@ const getNextUrl = () => { const getToken = props => { const { location } = props + if (location && location.search && location.search.match(/^\?token=/)) { return location.search.replace(/^\?token=/, '') } + return null } diff --git a/app/components/component-manuscript/src/components/ManuscriptPage.js b/app/components/component-manuscript/src/components/ManuscriptPage.js index 651957b5a5..8dc454b8d4 100644 --- a/app/components/component-manuscript/src/components/ManuscriptPage.js +++ b/app/components/component-manuscript/src/components/ManuscriptPage.js @@ -37,9 +37,11 @@ const query = gql` } ` +// eslint-disable-next-line react/prop-types const ManuscriptPage = ({ match, ...props }) => { const { data, loading, error } = useQuery(query, { variables: { + // eslint-disable-next-line react/prop-types id: match.params.version, }, }) @@ -56,4 +58,5 @@ const ManuscriptPage = ({ match, ...props }) => { /> ) } + export default ManuscriptPage diff --git a/app/components/component-manuscripts/src/Manuscripts.jsx b/app/components/component-manuscripts/src/Manuscripts.jsx index 4f940b0720..14b1829504 100644 --- a/app/components/component-manuscripts/src/Manuscripts.jsx +++ b/app/components/component-manuscripts/src/Manuscripts.jsx @@ -141,9 +141,10 @@ const Manuscripts = () => { </tr> </Header> <tbody> - {manuscripts.map((manuscript, key) => { + {manuscripts.map(function (manuscript, key) { const latestVersion = manuscript.manuscriptVersions?.[0] || manuscript + return ( <Manuscript key={latestVersion.id} diff --git a/app/components/component-review/src/components/metadata/ReviewMetadata.js b/app/components/component-review/src/components/metadata/ReviewMetadata.js index ece543a6f2..3b198faffb 100644 --- a/app/components/component-review/src/components/metadata/ReviewMetadata.js +++ b/app/components/component-review/src/components/metadata/ReviewMetadata.js @@ -1,3 +1,4 @@ +/* eslint-disable react/prop-types */ import React from 'react' import styled from 'styled-components' import { get } from 'lodash' @@ -11,9 +12,9 @@ import { SectionContent } from '../../../../shared' const Heading = styled.span` font-weight: inherit; + overflow: hidden; padding: 0 1em 0 0; text-overflow: ellipsis; - overflow: hidden; white-space: nowrap; ` @@ -30,8 +31,8 @@ const Heading = styled.span` // ` const Cell = styled.span` - padding: 0; grid-column: span 2 / span 2; + padding: 0; ` const getNote = (notes, type) => @@ -45,6 +46,7 @@ const getSupplementaryFiles = supplementary => const showFieldData = (manuscript, fieldName) => { const data = get(manuscript, fieldName) + // TODO: Make this generic somehow. Perhaps with an additional fieldType? if (Array.isArray(data) && fieldName === 'submission.links') { return data.map(link => ( @@ -54,11 +56,15 @@ const showFieldData = (manuscript, fieldName) => { </a> </p> )) - } else if (Array.isArray(data)) { + } + + if (Array.isArray(data)) { return data.join(', ') } + return data } + // Due to migration to new Data Model // Attachement component needs different data structure to work // needs to change the pubsweet ui Attachement to support the new Data Model diff --git a/app/components/component-submit/src/upload.js b/app/components/component-submit/src/upload.js index 2a33bc2cdd..dc0c4f3485 100644 --- a/app/components/component-submit/src/upload.js +++ b/app/components/component-submit/src/upload.js @@ -1,5 +1,6 @@ import config from 'config' import request from 'pubsweet-client/src/helpers/api' +// eslint-disable-next-line import/no-extraneous-dependencies import gql from 'graphql-tag' import currentRolesVar from '../../../shared/currentRolesVar' @@ -86,6 +87,7 @@ const createManuscriptMutation = gql` const uploadPromise = (files, client) => { const [file] = files + if (files.length > 1) { throw new Error('Only one manuscript file can be uploaded') } @@ -127,6 +129,7 @@ const createManuscriptPromise = ( let source let title let files = [] + if (file) { source = typeof response === 'string' ? response : undefined title = extractTitle(response) || generateTitle(file.name) @@ -201,14 +204,17 @@ export default ({ journals, currentUser, setConversion, + // eslint-disable-next-line consistent-return }) => async files => { setConversion({ converting: true }) let manuscriptData let uploadResponse + try { if (files) { const [file] = files const { data } = await uploadPromise(files, client) + if (skipXSweet(file)) { uploadResponse = { fileURL: data.upload.url, @@ -217,6 +223,7 @@ export default ({ } else { uploadResponse = await DocxToHTMLPromise(file, data) } + manuscriptData = await createManuscriptPromise( file, client, @@ -234,6 +241,7 @@ export default ({ undefined, ) } + return redirectPromise( setConversion, journals, diff --git a/app/components/xpub-journal/src/index.js b/app/components/xpub-journal/src/index.js index 053ce7c3fd..c4a699b76f 100644 --- a/app/components/xpub-journal/src/index.js +++ b/app/components/xpub-journal/src/index.js @@ -1,13 +1,13 @@ +/* eslint-disable react/destructuring-assignment */ import React from 'react' const JournalContext = React.createContext() -const JournalProvider = props => { - return ( - <JournalContext.Provider value={props.journal}> - {props.children} - </JournalContext.Provider> - ) -} +const JournalProvider = props => ( + // eslint-disable-next-line react/prop-types + <JournalContext.Provider value={props.journal}> + {props.children} + </JournalContext.Provider> +) export { JournalContext, JournalProvider } diff --git a/package.json b/package.json index 480aa0abe0..335d253b17 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "server": "pubsweet start:server", "server:test": "node node_modules/pubsweet-server/src/start", "start:server-and-client": "start-test server 'http://localhost:3000/healthcheck' client", - "start:services": "docker-compose up postgres", + "start:services": "docker-compose up db", "test:all:chrome": "start-test test:server-and-client 4000 test:chrome", "test:all:firefox": "start-test test:server-and-client 4000 test:firefox", "test:chrome": "cypress run --browser chrome", @@ -74,6 +74,7 @@ "apollo-link-context": "1.0.20", "apollo-link-schema": "1.2.5", "apollo-upload-client": "14.1.2", + "bcrypt": "^5.0.0", "config": "3.3.2", "faker": "4.1.0", "font-awesome": "4.7.0", @@ -84,6 +85,7 @@ "graphql-shield": "7.3.7", "graphql-tools": "4.0.8", "history": "4.10.1", + "husky": "^4.3.8", "jimp": "0.16.1", "joi": "10.6.0", "loadable-components": "0.4.0", @@ -104,7 +106,8 @@ "prop-types": "15.7.2", "pubsweet": "5.1.14", "pubsweet-client": "10.2.5", - "pubsweet-server": "13.11.1", + "pubsweet-server": "^13.11.6", + "re2": "^1.15.9", "react": "16.13.1", "react-dom": "16.13.1", "react-dropzone": "10.2.2", @@ -119,6 +122,7 @@ "react-visibility-sensor": "5.1.1", "styled-components": "4.4.1", "supertest": "3.4.2", + "url-regex-safe": "^1.0.2", "wax-prosemirror-core": "0.0.10", "wax-prosemirror-plugins": "0.0.10", "wax-prosemirror-schema": "0.0.10", @@ -146,7 +150,7 @@ "@babel/plugin-syntax-import-meta": "7.10.4", "@babel/preset-env": "7.11.5", "@babel/preset-react": "7.10.4", - "@coko/lint": "^1.3.0", + "@coko/lint": "^1.4.0", "babel-core": "7.0.0-bridge.0", "babel-jest": "23.6.0", "babel-loader": "8.1.0", @@ -156,8 +160,9 @@ "compression-webpack-plugin": "3.1.0", "copy-webpack-plugin": "4.6.0", "css-loader": "0.28.11", - "cypress": "5.3.0", + "cypress": "^6.2.0", "cypress-file-upload": "4.1.1", + "cypress-log-to-output": "^1.1.2", "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.11", "html-webpack-plugin": "3.2.0", diff --git a/server/app.js b/server/app.js index 157e621c65..4d22992bf1 100644 --- a/server/app.js +++ b/server/app.js @@ -1,3 +1,6 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable global-require */ +/* eslint-disable import/no-extraneous-dependencies */ const path = require('path') const config = require('config') @@ -10,7 +13,6 @@ const helmet = require('helmet') const cookieParser = require('cookie-parser') const bodyParser = require('body-parser') const passport = require('passport') -const gqlApi = require('./graphql') // const index = require('./routes/index') // const api = require('./routes/api') const logger = require('@pubsweet/logger') @@ -22,9 +24,10 @@ const registerComponents = require('pubsweet-server/src/register-components') // // Wax Collab requirements const WebSocket = require('ws') +const EventEmitter = require('events') const wsUtils = require('./wax-collab/server-util.js') // const cookie = require('cookie') -const EventEmitter = require('events') +const gqlApi = require('./graphql') const configureApp = app => { const models = require('@pubsweet/models') @@ -35,6 +38,7 @@ const configureApp = app => { app.use(bodyParser.json({ limit: '50mb' })) morgan.token('graphql', ({ body }, res, type) => { if (!body.operationName) return '' + switch (type) { case 'query': return body.query.replace(/\s+/g, ' ') @@ -66,6 +70,7 @@ const configureApp = app => { ), ) } + // Passport strategies app.use(passport.initialize()) const authentication = require('pubsweet-server/src/authentication') @@ -103,13 +108,20 @@ const configureApp = app => { if (err.name === 'ValidationError') { return res.status(STATUS.BAD_REQUEST).json({ message: err.message }) - } else if (err.name === 'ConflictError') { + } + + if (err.name === 'ConflictError') { return res.status(STATUS.CONFLICT).json({ message: err.message }) - } else if (err.name === 'AuthorizationError') { + } + + if (err.name === 'AuthorizationError') { return res.status(err.status).json({ message: err.message }) - } else if (err.name === 'AuthenticationError') { + } + + if (err.name === 'AuthenticationError') { return res.status(STATUS.UNAUTHORIZED).json({ message: err.message }) } + return res .status(err.status || STATUS.INTERNAL_SERVER_ERROR) .json({ message: err.message }) @@ -133,10 +145,12 @@ const configureApp = app => { serverProxy.emit('upgrade', request, socket, head, ...rest) } else { let user = null + if (request.headers.cookie) { // const cookies = cookie.parse(request.headers.cookie) // const user = cookies.user_identifier } + // TODO: Do real auth for Wax-collab user = 'test' // shortcut @@ -145,6 +159,7 @@ const configureApp = app => { socket.destroy() return } + wss.handleUpgrade(request, socket, head, ws => { wss.emit('connection', ws, request) }) diff --git a/server/component-xpub-review-backend/src/reviewBackend.js b/server/component-xpub-review-backend/src/reviewBackend.js index 1132bc19e4..316488528c 100644 --- a/server/component-xpub-review-backend/src/reviewBackend.js +++ b/server/component-xpub-review-backend/src/reviewBackend.js @@ -1,3 +1,5 @@ +/* eslint-disable global-require */ +/* eslint-disable import/no-extraneous-dependencies */ const { pick } = require('lodash') const config = require('config') const passport = require('passport') @@ -32,6 +34,7 @@ module.exports = app => { } const canViewVersion = await authsome.can(req.user, 'GET', version) + const canPatchVersion = await authsome.can( req.user, 'PATCH', @@ -40,9 +43,11 @@ module.exports = app => { if (!canPatchVersion || !canViewVersion) throw new AuthorizationError() let versionUpdateData = req.body.reviewers + if (canPatchVersion.filter) { versionUpdateData = canPatchVersion.filter(versionUpdateData) } + await version.updateProperties({ reviewers: versionUpdateData }) await version.save() @@ -71,11 +76,13 @@ module.exports = app => { } const canViewProject = await authsome.can(req.user, 'GET', project) + const canPatchProject = await authsome.can( req.user, 'PATCH', currentAndUpdateProject, ) + if (!canPatchProject || !canViewProject) throw new AuthorizationError() await Team.query().upsertGraphAndFetch( @@ -118,6 +125,7 @@ module.exports = app => { } const canViewVersion = await authsome.can(req.user, 'GET', version) + const canPatchVersion = await authsome.can( req.user, 'PATCH', @@ -126,14 +134,17 @@ module.exports = app => { if (!canPatchVersion || !canViewVersion) throw new AuthorizationError() let versionUpdateData = { decision: req.body.decision } + if (canPatchVersion.filter) { versionUpdateData = canPatchVersion.filter(versionUpdateData) } + await version.updateProperties(versionUpdateData) let nextVersionData let projectUpdateData = {} let message + switch (version.decision.recommendation) { case 'accept': projectUpdateData.status = 'accepted' @@ -159,6 +170,7 @@ module.exports = app => { 'files', 'notes', ]) + nextVersionData = { fragmentType: 'version', created: new Date(), @@ -177,16 +189,20 @@ module.exports = app => { let nextVersion let canViewNextVersion + if (nextVersionData) { const canCreateVersion = await authsome.can(req.user, 'POST', { path: '/collections/:collectionId/fragments', collection: project, fragment: nextVersionData, }) + if (!canCreateVersion) throw new AuthorizationError() + if (canCreateVersion.filter) { nextVersionData = canCreateVersion.filter(nextVersionData) } + nextVersion = new Fragment(nextVersionData) canViewNextVersion = await authsome.can(req.user, 'GET', nextVersion) @@ -195,15 +211,19 @@ module.exports = app => { currentAndUpdate = { current: project, update: req.body } const canViewProject = await authsome.can(req.user, 'GET', project) + const canPatchProject = await authsome.can( req.user, 'PATCH', currentAndUpdate, ) + if (!canPatchProject || !canViewProject) throw new AuthorizationError() + if (canPatchProject.filter) { projectUpdateData = canPatchProject.filter(projectUpdateData) } + await project.updateProperties(projectUpdateData) await Promise.all([ diff --git a/yarn.lock b/yarn.lock index 35239ae6a6..b367c0e140 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1365,10 +1365,10 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@coko/lint@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@coko/lint/-/lint-1.3.0.tgz#b51464ad04162a378a681a7ae22514e3ad18c2df" - integrity sha512-jBLcukH05btHV+EBZfwSou5FFAu6UrZKZPjP4wslLU7fGLFpOBl28mlLAKg8PpCcEISe0PK0TWZGtEJNQ1YDqA== +"@coko/lint@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@coko/lint/-/lint-1.4.0.tgz#476986325676607d89a23cca2566da31d1ebd5b3" + integrity sha512-ed9WswpDJoxB8VVja/CgFUGjD0NxoQDvD/BXJ5kM/X/AaFYeanY7nr1bI4nCcas/IHHDb9nnEPRulqfMCuMBLA== dependencies: "@commitlint/cli" "^8.3.5" "@commitlint/config-conventional" "^8.3.4" @@ -2338,6 +2338,21 @@ tmp-promise "^2.0.0" umzug "^2.1.0" +"@pubsweet/db-manager@^3.1.15": + version "3.1.15" + resolved "https://registry.yarnpkg.com/@pubsweet/db-manager/-/db-manager-3.1.15.tgz#692ef08407e1682b766296efd248bcb613d5bcd4" + integrity sha512-+Wu1uf1MoXRALW/VjXLZLviHK/ot8ILYg5EukPZJ8BOxiX533gEkM/d8x93UdIPVsTPibGeCbkczfPTgZMn/SA== + dependencies: + "@hapi/joi" "^14.3.0" + "@pubsweet/logger" "^0.2.50" + fs-extra "^8.1.0" + knex "^0.21.1" + lodash "^4.17.11" + objection "^2.1.3" + pg "^7.8.0" + tmp-promise "^2.0.0" + umzug "^2.1.0" + "@pubsweet/errors@^2.0.36": version "2.0.36" resolved "https://registry.yarnpkg.com/@pubsweet/errors/-/errors-2.0.36.tgz#afa254f26578468b6d1f8839ba6310e2fd7c6177" @@ -2345,6 +2360,13 @@ dependencies: http-status-codes "^1.3.0" +"@pubsweet/errors@^2.0.40": + version "2.0.40" + resolved "https://registry.yarnpkg.com/@pubsweet/errors/-/errors-2.0.40.tgz#911448a01dd42cc9e72666b8d966083af73c3acd" + integrity sha512-/xbJvsdt8oCWebr9uqFdiytPbpBMxReVxK0BtbHg4LA9Z2GSU/PP1vk+1IcyIxI4lhOMgC5lwkKWbufI4sOJ3g== + dependencies: + http-status-codes "^1.3.0" + "@pubsweet/job-xsweet@2.1.11": version "2.1.11" resolved "https://registry.yarnpkg.com/@pubsweet/job-xsweet/-/job-xsweet-2.1.11.tgz#a667f29912ce28df2a5929871cd1f4b4f2dcbb0a" @@ -2374,6 +2396,14 @@ "@hapi/joi" "^14.5.0" config "^3.0.1" +"@pubsweet/logger@^0.2.50": + version "0.2.50" + resolved "https://registry.yarnpkg.com/@pubsweet/logger/-/logger-0.2.50.tgz#b2553d94c7e83f8a152ae0f315a24154931a123f" + integrity sha512-Z36ZVgI6XCLHqqQf8L21uirJjeJOrb3FbCqHFy7ISQobDQ/907w2S9JR21jaYK8vyqtb0bpAWseh1niF91mw/Q== + dependencies: + "@hapi/joi" "^14.5.0" + config "^3.0.1" + "@pubsweet/model-user@6.0.3": version "6.0.3" resolved "https://registry.yarnpkg.com/@pubsweet/model-user/-/model-user-6.0.3.tgz#b0ad3e307e293d9794f20bcc3797164732eb221b" @@ -2399,6 +2429,13 @@ dependencies: "@pubsweet/logger" "^0.2.49" +"@pubsweet/models@^0.3.15": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@pubsweet/models/-/models-0.3.15.tgz#30170590045e2748f907930b7b3922f6a822fc74" + integrity sha512-CuE+5ZQNWS6UC5JGWzrMpoitK/bQjZ0aAAKqaPj5jaFnV3mtoYAv+D4NE40lzDRQDVFrRrNZbb9APvRiWiVrFg== + dependencies: + "@pubsweet/logger" "^0.2.50" + "@pubsweet/ui-toolkit@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@pubsweet/ui-toolkit/-/ui-toolkit-2.3.2.tgz#44b9b97b399027ef90bf0c30768475284f437fb4" @@ -4445,6 +4482,14 @@ bcrypt@^3.0.6: nan "2.14.0" node-pre-gyp "0.14.0" +bcrypt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.0.0.tgz#051407c7cd5ffbfb773d541ca3760ea0754e37e2" + integrity sha512-jB0yCBl4W/kVHM2whjfyqnxTmOHkCX4kHEa5nYKSoGeYe8YrjTYTc87/6bwt1g8cmV0QrbhKriETg9jWtcREhg== + dependencies: + node-addon-api "^3.0.0" + node-pre-gyp "0.15.0" + bfj@^6.1.1: version "6.1.2" resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" @@ -5209,6 +5254,14 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chrome-remote-interface@^0.27.1: + version "0.27.2" + resolved "https://registry.yarnpkg.com/chrome-remote-interface/-/chrome-remote-interface-0.27.2.tgz#e5605605f092b7ef8575d95304e004039c9d0ab9" + integrity sha512-pVLljQ29SAx8KIv5tSa9sIf8GrEsAZdPJoeWOmY3/nrIzFmE+EryNNHvDkddGod0cmAFTv+GmPG0uvzxi2NWsA== + dependencies: + commander "2.11.x" + ws "^6.1.0" + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -5542,6 +5595,11 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@2.11.x: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== + commander@2.17.x: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -5552,11 +5610,6 @@ commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.20.3, comm resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" @@ -6196,10 +6249,18 @@ cypress-file-upload@4.1.1: dependencies: mime "^2.4.4" -cypress@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-5.3.0.tgz#91122219ae66ab910058970dbf36619ab0fbde6c" - integrity sha512-XgebyqL7Th6/8YenE1ddb7+d4EiCG2Jvg/5c8+HPfFFY/gXnOVhoCVUU3KW8qg3JL7g0B+iJbHd5hxuCqbd1RQ== +cypress-log-to-output@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cypress-log-to-output/-/cypress-log-to-output-1.1.2.tgz#b9635a907ed06961cd53cc1bff8d6f55a981a773" + integrity sha512-C1+ECMc/XXc4HqAEHdlw0X2wFhcoZZ/4qXHZkOAU/rRXMQXnbiO7JJtpLCKrLfOXlxB+jFwDAIdlPxPMfV3cFw== + dependencies: + chalk "^2.4.2" + chrome-remote-interface "^0.27.1" + +cypress@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-6.2.0.tgz#1a8a7dd5bd08db3064551a9f12072963cc9337bf" + integrity sha512-m/rkcogYM9MTy8rbsZgyS5wT2L/J+B5V2bY2ztkDNMyqhk/oZgUF4KTWVLzkW2I+scg0iAddca95tLlt7XnAtw== dependencies: "@cypress/listr-verbose-renderer" "^0.4.1" "@cypress/request" "^2.88.5" @@ -6213,7 +6274,7 @@ cypress@5.3.0: chalk "^4.1.0" check-more-types "^2.24.0" cli-table3 "~0.6.0" - commander "^4.1.1" + commander "^5.1.0" common-tags "^1.8.0" debug "^4.1.1" eventemitter2 "^6.4.2" @@ -6231,10 +6292,10 @@ cypress@5.3.0: minimist "^1.2.5" moment "^2.27.0" ospath "^1.2.2" - pretty-bytes "^5.3.0" + pretty-bytes "^5.4.1" ramda "~0.26.1" request-progress "^3.0.0" - supports-color "^7.1.0" + supports-color "^7.2.0" tmp "~0.2.1" untildify "^4.0.0" url "^0.11.0" @@ -8174,6 +8235,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find-versions@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" @@ -8181,6 +8250,13 @@ find-versions@^3.2.0: dependencies: semver-regex "^2.0.0" +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== + dependencies: + semver-regex "^3.1.2" + findup-sync@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" @@ -9456,6 +9532,22 @@ husky@^4.2.3: slash "^3.0.0" which-pm-runs "^1.0.0" +husky@^4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" + integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== + dependencies: + chalk "^4.0.0" + ci-info "^2.0.0" + compare-versions "^3.6.0" + cosmiconfig "^7.0.0" + find-versions "^4.0.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^5.0.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" + i@0.3.x: version "0.3.6" resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" @@ -9695,6 +9787,11 @@ install-artifact-from-github@^1.0.2: resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.0.2.tgz#e1e478dd29880b9112ecd684a84029603e234a9d" integrity sha512-yuMFBSVIP3vD0SDBGUqeIpgOAIlFx8eQFknQObpkYEM5gsl9hy6R9Ms3aV+Vw9MMyYsoPMeex0XDnfgY7uzc+Q== +install-artifact-from-github@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.2.0.tgz#adcbd123c16a4337ec44ea76d0ebf253cc16b074" + integrity sha512-3OxCPcY55XlVM3kkfIpeCgmoSKnMsz2A3Dbhsq0RXpIknKQmrX1YiznCeW9cD2ItFmDxziA3w6Eg8d80AoL3oA== + internal-ip@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" @@ -11450,6 +11547,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash-es@^4.17.11, lodash-es@^4.17.14: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" @@ -12412,6 +12516,11 @@ nan@^2.12.1, nan@^2.14.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== +nan@^2.14.2: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -12478,6 +12587,15 @@ needle@^2.2.1: iconv-lite "^0.4.4" sax "^1.2.4" +needle@^2.5.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" + integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -12510,6 +12628,11 @@ nocache@2.1.0: resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f" integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q== +node-addon-api@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" + integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== + node-dev@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/node-dev/-/node-dev-4.3.0.tgz#de98164a86bbb6dbd7378e23f3d6638041d4a81f" @@ -12561,6 +12684,22 @@ node-gyp@^7.0.0: tar "^6.0.1" which "^2.0.2" +node-gyp@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.3" + nopt "^5.0.0" + npmlog "^4.1.2" + request "^2.88.2" + rimraf "^3.0.2" + semver "^7.3.2" + tar "^6.0.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -12622,6 +12761,22 @@ node-pre-gyp@0.14.0: semver "^5.3.0" tar "^4.4.2" +node-pre-gyp@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz#c2fc383276b74c7ffa842925241553e8b40f1087" + integrity sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.3" + needle "^2.5.0" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + node-releases@^1.1.58: version "1.1.59" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.59.tgz#4d648330641cec704bff10f8e4fe28e453ab8e8e" @@ -12661,6 +12816,13 @@ nopt@^4.0.1, nopt@^4.0.3: abbrev "1" osenv "^0.1.4" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" @@ -13166,6 +13328,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -13187,6 +13356,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -13731,6 +13907,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + pkginfo@0.3.x: version "0.3.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" @@ -14183,10 +14366,10 @@ prettier@^2.0.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== -pretty-bytes@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" - integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== +pretty-bytes@^5.4.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" + integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== pretty-error@^2.0.2: version "2.1.1" @@ -14526,7 +14709,7 @@ pubsweet-client@10.2.5: styled-normalize "^8.0.6" subscriptions-transport-ws "^0.9.12" -pubsweet-server@13.11.1, pubsweet-server@^13.11.1: +pubsweet-server@^13.11.1: version "13.11.1" resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-13.11.1.tgz#8ebed92e8cfddee3aa65543473896f0cc66062e2" integrity sha512-MT6KincsVjgYjd3FtNqQd2AcuM39vM9Ebe6AlhFUJVhgNmIuFAXrg3p/pjxDxkCWKDs/oI9V8brldndzvU29UQ== @@ -14563,11 +14746,53 @@ pubsweet-server@13.11.1, pubsweet-server@^13.11.1: subscriptions-transport-ws "^0.9.12" waait "^1.0.2" +pubsweet-server@^13.11.6: + version "13.11.6" + resolved "https://registry.yarnpkg.com/pubsweet-server/-/pubsweet-server-13.11.6.tgz#780e2a250de7f737c3b9feeee03dd7e03513c0f6" + integrity sha512-9LZfE6PYbtM4NLgFufKbp96CVv0sfMp0LyO+8vsCnEZW5gGXcPSSkokDoAtIoxxje4OcnQkAfoKv1CqxKaWiLA== + dependencies: + "@pubsweet/db-manager" "^3.1.15" + "@pubsweet/errors" "^2.0.40" + "@pubsweet/logger" "^0.2.50" + "@pubsweet/models" "^0.3.15" + apollo-server-express "^2.4.8" + authsome "^0.1.0" + body-parser "^1.15.2" + config "^3.0.1" + cookie-parser "^1.4.3" + dataloader "^1.4.0" + dotenv "^4.0.0" + express "^4.16.1" + fs-extra "^8.1.0" + graphql "^14.2.1" + graphql-postgres-subscriptions "^1.0.4" + helmet "^3.8.1" + http-status-codes "^1.0.6" + jsonwebtoken "^8.4.0" + lodash "^4.0.0" + morgan "^1.8.2" + multer "^1.1.0" + objection "^2.1.3" + passport "^0.4.0" + passport-anonymous "^1.0.1" + passport-http-bearer "^1.0.1" + passport-local "^1.0.0" + pg "^7.4.1" + pg-boss "^3.1.2" + pubsweet-sse "^1.0.44" + subscriptions-transport-ws "^0.9.12" + waait "^1.0.2" + pubsweet-sse@^1.0.40: version "1.0.40" resolved "https://registry.yarnpkg.com/pubsweet-sse/-/pubsweet-sse-1.0.40.tgz#93736085ca472ba28b11d08a212a5b96dfaab314" integrity sha512-1hVcG3D4wxMyA979pllqIIBrnK8i9BilEvF1xsIu20zTh053eA5bMbJXxR5mm8OUGNqXdqqoz8LsZuJqR43XNQ== +pubsweet-sse@^1.0.44: + version "1.0.44" + resolved "https://registry.yarnpkg.com/pubsweet-sse/-/pubsweet-sse-1.0.44.tgz#71f7d4bb8faad1bb35b40b0c54b89c95397cad67" + integrity sha512-vstlq2qiJHO3vn8nLpMFWRdIIHmotJKECjm8FXbU+pqiqs28/U1LsFOADVRhRn9nRtobdSF2soQYWA4FpTD6yg== + pubsweet@5.1.14: version "5.1.14" resolved "https://registry.yarnpkg.com/pubsweet/-/pubsweet-5.1.14.tgz#a4f8756e72b3a8c63b24344d52e72d7bdd3a5180" @@ -14794,6 +15019,15 @@ re2@^1.15.4: nan "^2.14.1" node-gyp "^7.0.0" +re2@^1.15.9: + version "1.15.9" + resolved "https://registry.yarnpkg.com/re2/-/re2-1.15.9.tgz#9ed16171edcb0bc4f0e239bf55229ff3f26acbe3" + integrity sha512-AXWEhpMTBdC+3oqbjdU07dk0pBCvxh5vbOMLERL6Y8FYBSGn4vXlLe8cYszn64Yy7H8keVMrgPzoSvOd4mePpg== + dependencies: + install-artifact-from-github "^1.2.0" + nan "^2.14.2" + node-gyp "^7.1.2" + react-base16-styling@^0.5.1: version "0.5.3" resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.5.3.tgz#3858f24e9c4dd8cbd3f702f3f74d581ca2917269" @@ -15910,6 +16144,11 @@ semver-regex@^2.0.0: resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +semver-regex@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" + integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -16926,6 +17165,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" @@ -17011,7 +17257,7 @@ tar@^4.4.2: safe-buffer "^5.1.2" yallist "^3.0.3" -tar@^6.0.1: +tar@^6.0.1, tar@^6.0.2: version "6.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== @@ -17783,7 +18029,7 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" -url-regex-safe@~1.0.2: +url-regex-safe@^1.0.2, url-regex-safe@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/url-regex-safe/-/url-regex-safe-1.0.2.tgz#822cbab107d7f4f80342f0f0798acf63cac9fd1d" integrity sha512-t1doIKbYDBRyqXZz7A98AXH/zimKmYapxFjBZwcz3BmqjB921rUPEUokAaShKyenaX3McOM8FbkWLvFvX3Jsyw== @@ -18640,7 +18886,7 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^6.0.0, ws@^6.2.1: +ws@^6.0.0, ws@^6.1.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== @@ -18890,6 +19136,11 @@ yjs@13.3.0: dependencies: lib0 "^0.2.32" +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + yup@^0.29.3: version "0.29.3" resolved "https://registry.yarnpkg.com/yup/-/yup-0.29.3.tgz#69a30fd3f1c19f5d9e31b1cf1c2b851ce8045fea" -- GitLab