-
+
-
@@ -71,6 +71,11 @@ export default {
}
},
computed: {
+ translateDistance() {
+ if (!this.userCanUpdate && !this.userCanDelete) return 'translate-x-0'
+ else if (!this.userCanUpdate || !this.userCanDelete) return '-translate-x-12'
+ return '-translate-x-24'
+ },
media() {
return this.book.media || {}
},
@@ -113,6 +118,12 @@ export default {
coverWidth() {
if (this.bookCoverAspectRatio === 1) return this.coverSize * 1.6
return this.coverSize
+ },
+ userCanUpdate() {
+ return this.$store.getters['user/getUserCanUpdate']
+ },
+ userCanDelete() {
+ return this.$store.getters['user/getUserCanDelete']
}
},
methods: {
diff --git a/client/pages/collection/_id.vue b/client/pages/collection/_id.vue
index d55cb049..31bddca0 100644
--- a/client/pages/collection/_id.vue
+++ b/client/pages/collection/_id.vue
@@ -19,9 +19,9 @@
{{ streaming ? 'Streaming' : 'Play' }}
-
+
-
+
@@ -92,6 +92,12 @@ export default {
},
showPlayButton() {
return this.playableBooks.length
+ },
+ userCanUpdate() {
+ return this.$store.getters['user/getUserCanUpdate']
+ },
+ userCanDelete() {
+ return this.$store.getters['user/getUserCanDelete']
}
},
methods: {
diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue
index fe4e6f01..03c52696 100644
--- a/client/pages/item/_id/index.vue
+++ b/client/pages/item/_id/index.vue
@@ -150,7 +150,7 @@
-
+
diff --git a/server/controllers/CollectionController.js b/server/controllers/CollectionController.js
index 5d14530a..d3ae4917 100644
--- a/server/controllers/CollectionController.js
+++ b/server/controllers/CollectionController.js
@@ -24,18 +24,11 @@ class CollectionController {
}
findOne(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
- res.json(collection.toJSONExpanded(this.db.libraryItems))
+ res.json(req.collection.toJSONExpanded(this.db.libraryItems))
}
async update(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
+ const collection = req.collection
var wasUpdated = collection.update(req.body)
var jsonExpanded = collection.toJSONExpanded(this.db.libraryItems)
if (wasUpdated) {
@@ -46,10 +39,7 @@ class CollectionController {
}
async delete(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
+ const collection = req.collection
var jsonExpanded = collection.toJSONExpanded(this.db.libraryItems)
await this.db.removeEntity('collection', collection.id)
this.emitter('collection_removed', jsonExpanded)
@@ -57,10 +47,7 @@ class CollectionController {
}
async addBook(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
+ const collection = req.collection
var libraryItem = this.db.libraryItems.find(li => li.id === req.body.id)
if (!libraryItem) {
return res.status(500).send('Book not found')
@@ -80,11 +67,7 @@ class CollectionController {
// DELETE: api/collections/:id/book/:bookId
async removeBook(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
-
+ const collection = req.collection
if (collection.books.includes(req.params.bookId)) {
collection.removeBook(req.params.bookId)
var jsonExpanded = collection.toJSONExpanded(this.db.libraryItems)
@@ -96,10 +79,7 @@ class CollectionController {
// POST: api/collections/:id/batch/add
async addBatch(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
+ const collection = req.collection
if (!req.body.books || !req.body.books.length) {
return res.status(500).send('Invalid request body')
}
@@ -120,10 +100,7 @@ class CollectionController {
// POST: api/collections/:id/batch/remove
async removeBatch(req, res) {
- var collection = this.db.collections.find(c => c.id === req.params.id)
- if (!collection) {
- return res.status(404).send('Collection not found')
- }
+ const collection = req.collection
if (!req.body.books || !req.body.books.length) {
return res.status(500).send('Invalid request body')
}
@@ -141,5 +118,25 @@ class CollectionController {
}
res.json(collection.toJSONExpanded(this.db.libraryItems))
}
+
+ middleware(req, res, next) {
+ if (req.params.id) {
+ var collection = this.db.collections.find(c => c.id === req.params.id)
+ if (!collection) {
+ return res.status(404).send('Collection not found')
+ }
+ req.collection = collection
+ }
+
+ if (req.method == 'DELETE' && !req.user.canDelete) {
+ Logger.warn(`[CollectionController] User attempted to delete without permission`, req.user.username)
+ return res.sendStatus(403)
+ } else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
+ Logger.warn('[CollectionController] User attempted to update without permission', req.user.username)
+ return res.sendStatus(403)
+ }
+
+ next()
+ }
}
module.exports = new CollectionController()
\ No newline at end of file
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index 2ac09cef..2ad782f0 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -116,16 +116,16 @@ class ApiRouter {
//
// Collection Routes
//
- this.router.post('/collections', CollectionController.create.bind(this))
+ this.router.post('/collections', CollectionController.middleware.bind(this), CollectionController.create.bind(this))
this.router.get('/collections', CollectionController.findAll.bind(this))
- this.router.get('/collections/:id', CollectionController.findOne.bind(this))
- this.router.patch('/collections/:id', CollectionController.update.bind(this))
- this.router.delete('/collections/:id', CollectionController.delete.bind(this))
+ this.router.get('/collections/:id', CollectionController.middleware.bind(this), CollectionController.findOne.bind(this))
+ this.router.patch('/collections/:id', CollectionController.middleware.bind(this), CollectionController.update.bind(this))
+ this.router.delete('/collections/:id', CollectionController.middleware.bind(this), CollectionController.delete.bind(this))
- this.router.post('/collections/:id/book', CollectionController.addBook.bind(this))
- this.router.delete('/collections/:id/book/:bookId', CollectionController.removeBook.bind(this))
- this.router.post('/collections/:id/batch/add', CollectionController.addBatch.bind(this))
- this.router.post('/collections/:id/batch/remove', CollectionController.removeBatch.bind(this))
+ this.router.post('/collections/:id/book', CollectionController.middleware.bind(this), CollectionController.addBook.bind(this))
+ this.router.delete('/collections/:id/book/:bookId', CollectionController.middleware.bind(this), CollectionController.removeBook.bind(this))
+ this.router.post('/collections/:id/batch/add', CollectionController.middleware.bind(this), CollectionController.addBatch.bind(this))
+ this.router.post('/collections/:id/batch/remove', CollectionController.middleware.bind(this), CollectionController.removeBatch.bind(this))
//
// Current User Routes (Me)