Open media item share sessions shown on listening sessions page, create device info for share sessions

This commit is contained in:
advplyr 2024-06-30 16:36:00 -05:00
parent d7ace4d1dc
commit 8e286a6070
8 changed files with 104 additions and 40 deletions

View file

@ -2,8 +2,10 @@ const Logger = require('../Logger')
const Database = require('../Database')
const { toNumber, isUUID } = require('../utils/index')
const ShareManager = require('../managers/ShareManager')
class SessionController {
constructor() { }
constructor() {}
async findOne(req, res) {
return res.json(req.playbackSession)
@ -12,9 +14,9 @@ class SessionController {
/**
* GET: /api/sessions
* @this import('../routers/ApiRouter')
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
async getAllWithUserData(req, res) {
if (!req.user.isAdminOrUp) {
@ -68,15 +70,13 @@ class SessionController {
const { rows, count } = await Database.playbackSessionModel.findAndCountAll({
where,
include,
order: [
[orderKey, orderDesc]
],
order: [[orderKey, orderDesc]],
limit: itemsPerPage,
offset: itemsPerPage * page
})
// Map playback sessions to old playback sessions
const sessions = rows.map(session => {
const sessions = rows.map((session) => {
const oldPlaybackSession = Database.playbackSessionModel.getOldPlaybackSession(session)
if (session.user) {
return {
@ -112,15 +112,18 @@ class SessionController {
}
const minifiedUserObjects = await Database.userModel.getMinifiedUserObjects()
const openSessions = this.playbackSessionManager.sessions.map(se => {
const openSessions = this.playbackSessionManager.sessions.map((se) => {
return {
...se.toJSON(),
user: minifiedUserObjects.find(u => u.id === se.userId) || null
user: minifiedUserObjects.find((u) => u.id === se.userId) || null
}
})
const shareSessions = ShareManager.openSharePlaybackSessions.map((se) => se.toJSON())
res.json({
sessions: openSessions
sessions: openSessions,
shareSessions
})
}
@ -157,12 +160,12 @@ class SessionController {
/**
* POST: /api/sessions/batch/delete
* @this import('../routers/ApiRouter')
*
*
* @typedef batchDeleteReqBody
* @property {string[]} sessions
*
* @param {import('express').Request<{}, {}, batchDeleteReqBody, {}>} req
* @param {import('express').Response} res
*
* @param {import('express').Request<{}, {}, batchDeleteReqBody, {}>} req
* @param {import('express').Response} res
*/
async batchDelete(req, res) {
if (!req.user.isAdminOrUp) {
@ -170,7 +173,7 @@ class SessionController {
return res.sendStatus(403)
}
// Validate session ids
if (!req.body.sessions?.length || !Array.isArray(req.body.sessions) || req.body.sessions.some(s => !isUUID(s))) {
if (!req.body.sessions?.length || !Array.isArray(req.body.sessions) || req.body.sessions.some((s) => !isUUID(s))) {
Logger.error(`[SessionController] Invalid request body. "sessions" array is required`, req.body)
return res.status(400).send('Invalid request body. "sessions" array of session id strings is required.')
}
@ -239,4 +242,4 @@ class SessionController {
next()
}
}
module.exports = new SessionController()
module.exports = new SessionController()

View file

@ -1,4 +1,4 @@
const uuidv4 = require('uuid').v4
const uuid = require('uuid')
const Path = require('path')
const { Op } = require('sequelize')
const Logger = require('../Logger')
@ -18,6 +18,8 @@ class ShareController {
* GET: /api/share/:slug
* Get media item share by slug
*
* @this {import('../routers/PublicRouter')}
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
@ -28,7 +30,8 @@ class ShareController {
const mediaItemShare = ShareManager.findBySlug(slug)
if (!mediaItemShare) {
return res.status(404)
Logger.warn(`[ShareController] Media item share not found with slug ${slug}`)
return res.sendStatus(404)
}
if (mediaItemShare.expiresAt && mediaItemShare.expiresAt.valueOf() < Date.now()) {
ShareManager.removeMediaItemShare(mediaItemShare.id)
@ -43,7 +46,10 @@ class ShareController {
return res.json(mediaItemShare)
} else {
Logger.info(`[ShareController] Share playback session not found with id ${req.cookies.share_session_id}`)
res.clearCookie('share_session_id')
if (!uuid.validate(req.cookies.share_session_id) || uuid.version(req.cookies.share_session_id) !== 4) {
Logger.warn(`[ShareController] Invalid share session id ${req.cookies.share_session_id}`)
res.clearCookie('share_session_id')
}
}
}
@ -75,11 +81,18 @@ class ShareController {
startTime = 0
}
const shareSessionId = req.cookies.share_session_id || uuid.v4()
const clientDeviceInfo = {
clientName: 'Abs Web Share',
deviceId: shareSessionId
}
const deviceInfo = await this.playbackSessionManager.getDeviceInfo(req, clientDeviceInfo)
const newPlaybackSession = new PlaybackSession()
newPlaybackSession.setData(oldLibraryItem, null, 'web-public', null, startTime)
newPlaybackSession.setData(oldLibraryItem, null, 'web-share', deviceInfo, startTime)
newPlaybackSession.audioTracks = publicTracks
newPlaybackSession.playMethod = PlayMethod.DIRECTPLAY
newPlaybackSession.shareSessionId = uuidv4() // New share session id
newPlaybackSession.shareSessionId = shareSessionId
newPlaybackSession.mediaItemShareId = mediaItemShare.id
newPlaybackSession.coverAspectRatio = oldLibraryItem.librarySettings.coverAspectRatio
@ -119,7 +132,6 @@ class ShareController {
const playbackSession = ShareManager.findPlaybackSessionBySessionId(req.cookies.share_session_id)
if (!playbackSession || playbackSession.mediaItemShareId !== mediaItemShare.id) {
res.clearCookie('share_session_id')
return res.status(404).send('Share session not found')
}
@ -160,7 +172,6 @@ class ShareController {
const playbackSession = ShareManager.findPlaybackSessionBySessionId(req.cookies.share_session_id)
if (!playbackSession || playbackSession.mediaItemShareId !== mediaItemShare.id) {
res.clearCookie('share_session_id')
return res.status(404).send('Share session not found')
}
@ -211,7 +222,6 @@ class ShareController {
const playbackSession = ShareManager.findPlaybackSessionBySessionId(req.cookies.share_session_id)
if (!playbackSession || playbackSession.mediaItemShareId !== mediaItemShare.id) {
res.clearCookie('share_session_id')
return res.status(404).send('Share session not found')
}