diff --git a/packages/component-manuscript-manager/src/Collections.js b/packages/component-manuscript-manager/src/Collections.js index 8ce7c79779abb552a2728ad835b3e078d21ccaa8..178ca4dbc17d1f90bfa15a11f514364e95092b06 100644 --- a/packages/component-manuscript-manager/src/Collections.js +++ b/packages/component-manuscript-manager/src/Collections.js @@ -36,6 +36,12 @@ const Collections = app => { authBearer, require(`${routePath}/get`)(app.locals.models), ) + + app.delete( + '/api/collections/:collectionId', + authBearer, + require(`${routePath}/delete`)(app.locals.models), + ) } module.exports = Collections diff --git a/packages/component-manuscript-manager/src/routes/collections/delete.js b/packages/component-manuscript-manager/src/routes/collections/delete.js new file mode 100644 index 0000000000000000000000000000000000000000..b2a85a1b05411dc766cd6f3bcbc2901e85cbb297 --- /dev/null +++ b/packages/component-manuscript-manager/src/routes/collections/delete.js @@ -0,0 +1,81 @@ +const { get, remove, concat } = require('lodash') +const config = require('config') + +const { + Team, + services, + authsome: authsomeHelper, +} = require('pubsweet-component-helper-service') + +const { + deleteFilesS3, +} = require('pubsweet-component-mts-package/src/PackageManager') + +const s3Config = get(config, 'pubsweet-component-aws-s3', {}) + +module.exports = models => async (req, res) => { + const { collectionId } = req.params + let collection, fragment + try { + collection = await models.Collection.find(collectionId) + + const fragmentId = collection.fragments[0] + if (!collection.fragments.includes(fragmentId)) + return res.status(400).json({ + error: `Collection and fragment do not match.`, + }) + + fragment = await models.Fragment.find(fragmentId) + + const authsome = authsomeHelper.getAuthsome(models) + + const canDelete = await authsome.can(req.user, 'DELETE', collection) + if (!canDelete) + return res.status(403).json({ + error: 'Unauthorized.', + }) + + const teamHelper = new Team({ + TeamModel: models.Team, + fragmentId, + collectionId, + }) + const team = await teamHelper.getTeam({ + role: 'author', + objectType: 'fragment', + }) + + await Promise.all( + team.members.map(async member => { + const user = await models.User.find(member) + + remove(user.teams, teamId => teamId === team.id) + + return user.save() + }), + ) + + await team.delete() + + const fileKeys = concat( + fragment.files.manuscripts, + fragment.files.coverLetter, + fragment.files.supplementary, + ).map(file => `${fragment.id}/${file.id}`) + + if (fileKeys.length !== 0) { + await deleteFilesS3({ fileKeys, s3Config }) + } + + await fragment.delete() + + await collection.delete() + + return res.status(200).json() + } catch (e) { + const notFoundError = await services.handleNotFoundError(e, 'Item') + return res.status(notFoundError.status).json({ + error: notFoundError.message, + }) + } +} diff --git a/packages/component-mts-package/src/PackageManager.js b/packages/component-mts-package/src/PackageManager.js index b98dbf10308c84b927b10d3f670b285a1b6ca8b7..cb9b8ea4c9fd644ef72c146706dde13348283cc4 100644 --- a/packages/component-mts-package/src/PackageManager.js +++ b/packages/component-mts-package/src/PackageManager.js @@ -115,6 +115,26 @@ const uploadFiles = async ({ filename, s3Config, config }) => { .catch(fileError(filename)) } +const deleteFilesS3 = async ({ fileKeys, s3Config }) => { + AWS.config.update({ + secretAccessKey: s3Config.secretAccessKey, + accessKeyId: s3Config.accessKeyId, + region: s3Config.region, + }) + const s3 = new AWS.S3() + + const params = { + Bucket: s3Config.bucket, + Delete: { + Objects: fileKeys.map(file => ({ Key: file })), + }, + } + + const deleteObjectsS3 = promisify(s3.deleteObjects.bind(s3)) + + return deleteObjectsS3(params) +} + const deleteFile = filename => { fs.access(filename, fs.constants.F_OK, err => { if (!err) { @@ -138,4 +158,5 @@ const uploadFTP = ({ filename, config }) => { module.exports = { createFilesPackage, uploadFiles, + deleteFilesS3, }