diff --git a/client/components/modals/ListeningSessionModal.vue b/client/components/modals/ListeningSessionModal.vue
index f9994e70..2b8edc3d 100644
--- a/client/components/modals/ListeningSessionModal.vue
+++ b/client/components/modals/ListeningSessionModal.vue
@@ -1,5 +1,5 @@
-
+
Session {{ _session.id }}
@@ -96,6 +96,10 @@
Type: {{ deviceInfo.deviceType }}
+
+
+ Delete
+
@@ -110,7 +114,9 @@ export default {
}
},
data() {
- return {}
+ return {
+ processing: false
+ }
},
computed: {
show: {
@@ -147,7 +153,37 @@ export default {
return 'Unknown'
}
},
- methods: {},
+ methods: {
+ deleteSessionClick() {
+ const payload = {
+ message: `Are you sure you want to delete this session?`,
+ callback: (confirmed) => {
+ if (confirmed) {
+ this.deleteSession()
+ }
+ },
+ type: 'yesNo'
+ }
+ this.$store.commit('globals/setConfirmPrompt', payload)
+ },
+ deleteSession() {
+ this.processing = true
+ this.$axios
+ .$delete(`/api/sessions/${this._session.id}`)
+ .then(() => {
+ this.processing = false
+ this.$toast.success('Session deleted successfully')
+ this.$emit('removedSession')
+ this.show = false
+ })
+ .catch((error) => {
+ this.processing = false
+ console.error('Failed to delete session', error)
+ var errMsg = error.response ? error.response.data || '' : ''
+ this.$toast.error(errMsg || 'Failed to delete session')
+ })
+ }
+ },
mounted() {}
}
\ No newline at end of file
diff --git a/client/pages/config/sessions.vue b/client/pages/config/sessions.vue
index 8eb3c598..960d63b8 100644
--- a/client/pages/config/sessions.vue
+++ b/client/pages/config/sessions.vue
@@ -58,7 +58,7 @@
No sessions yet...
-
+
@@ -111,6 +111,9 @@ export default {
}
},
methods: {
+ removedSession() {
+ this.loadSessions(this.currentPage)
+ },
async clickCurrentTime(session) {
if (this.processingGoToTimestamp) return
this.processingGoToTimestamp = true
diff --git a/client/pages/config/users/_id/sessions.vue b/client/pages/config/users/_id/sessions.vue
index c01786bb..5b1fb7e3 100644
--- a/client/pages/config/users/_id/sessions.vue
+++ b/client/pages/config/users/_id/sessions.vue
@@ -62,7 +62,7 @@
-
+
@@ -98,6 +98,9 @@ export default {
}
},
methods: {
+ removedSession() {
+ this.loadSessions(this.currentPage)
+ },
async clickCurrentTime(session) {
if (this.processingGoToTimestamp) return
this.processingGoToTimestamp = true
diff --git a/server/Db.js b/server/Db.js
index c9911089..4c2d55c3 100644
--- a/server/Db.js
+++ b/server/Db.js
@@ -183,17 +183,6 @@ class Db {
getLibraryItemsInLibrary(libraryId) {
return this.libraryItems.filter(li => li.libraryId === libraryId)
}
- getPlaybackSession(id) {
- return this.sessionsDb.select((pb) => pb.id == id).then((results) => {
- if (results.data.length) {
- return new PlaybackSession(results.data[0])
- }
- return null
- }).catch((error) => {
- Logger.error('Failed to get session', error)
- return null
- })
- }
async updateLibraryItem(libraryItem) {
return this.updateLibraryItems([libraryItem])
@@ -452,6 +441,18 @@ class Db {
})
}
+ getPlaybackSession(id) {
+ return this.sessionsDb.select((pb) => pb.id == id).then((results) => {
+ if (results.data.length) {
+ return new PlaybackSession(results.data[0])
+ }
+ return null
+ }).catch((error) => {
+ Logger.error('Failed to get session', error)
+ return null
+ })
+ }
+
selectUserSessions(userId) {
return this.sessionsDb.select((session) => session.userId === userId).then((results) => {
return results.data || []
diff --git a/server/controllers/SessionController.js b/server/controllers/SessionController.js
index 2a7ff059..fc3a25ef 100644
--- a/server/controllers/SessionController.js
+++ b/server/controllers/SessionController.js
@@ -42,7 +42,7 @@ class SessionController {
res.json(payload)
}
- getSession(req, res) {
+ getOpenSession(req, res) {
var libraryItem = this.db.getLibraryItem(req.session.libraryItemId)
var sessionForClient = req.session.toJSONForClient(libraryItem)
res.json(sessionForClient)
@@ -58,12 +58,24 @@ class SessionController {
this.playbackSessionManager.closeSessionRequest(req.user, req.session, req.body, res)
}
+ // DELETE: api/session/:id
+ async delete(req, res) {
+ // if session is open then remove it
+ const openSession = this.playbackSessionManager.getSession(req.session.id)
+ if (openSession) {
+ await this.playbackSessionManager.removeSession(req.session.id)
+ }
+
+ await this.db.removeEntity('session', req.session.id)
+ res.sendStatus(200)
+ }
+
// POST: api/session/local
syncLocal(req, res) {
this.playbackSessionManager.syncLocalSessionRequest(req.user, req.body, res)
}
- middleware(req, res, next) {
+ openSessionMiddleware(req, res, next) {
var playbackSession = this.playbackSessionManager.getSession(req.params.id)
if (!playbackSession) return res.sendStatus(404)
@@ -75,5 +87,21 @@ class SessionController {
req.session = playbackSession
next()
}
+
+ async middleware(req, res, next) {
+ var playbackSession = await this.db.getPlaybackSession(req.params.id)
+ if (!playbackSession) return res.sendStatus(404)
+
+ if (req.method == 'DELETE' && !req.user.canDelete) {
+ Logger.warn(`[SessionController] User attempted to delete without permission`, req.user)
+ return res.sendStatus(403)
+ } else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
+ Logger.warn('[SessionController] User attempted to update without permission', req.user.username)
+ return res.sendStatus(403)
+ }
+
+ req.session = playbackSession
+ next()
+ }
}
module.exports = new SessionController()
\ No newline at end of file
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index c4bc0385..36bbc57d 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -175,9 +175,11 @@ class ApiRouter {
// Playback Session Routes
//
this.router.get('/sessions', SessionController.getAllWithUserData.bind(this))
- this.router.get('/session/:id', SessionController.middleware.bind(this), SessionController.getSession.bind(this))
- this.router.post('/session/:id/sync', SessionController.middleware.bind(this), SessionController.sync.bind(this))
- this.router.post('/session/:id/close', SessionController.middleware.bind(this), SessionController.close.bind(this))
+ this.router.delete('/sessions/:id', SessionController.middleware.bind(this), SessionController.delete.bind(this))
+ // TODO: Update these endpoints because they are only for open playback sessions
+ this.router.get('/session/:id', SessionController.openSessionMiddleware.bind(this), SessionController.getOpenSession.bind(this))
+ this.router.post('/session/:id/sync', SessionController.openSessionMiddleware.bind(this), SessionController.sync.bind(this))
+ this.router.post('/session/:id/close', SessionController.openSessionMiddleware.bind(this), SessionController.close.bind(this))
this.router.post('/session/local', SessionController.syncLocal.bind(this))
//