mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-08 00:08:14 +01:00
Update:Express middleware sets req.user to new data model, openid permissions functions moved to new data model
This commit is contained in:
parent
29a15858f4
commit
2472b86284
@ -152,6 +152,8 @@ class Auth {
|
||||
/**
|
||||
* Finds an existing user by OpenID subject identifier, or by email/username based on server settings,
|
||||
* or creates a new user if configured to do so.
|
||||
*
|
||||
* @returns {import('./models/User')|null}
|
||||
*/
|
||||
async findOrCreateUser(userinfo) {
|
||||
let user = await Database.userModel.getUserByOpenIDSub(userinfo.sub)
|
||||
@ -307,9 +309,8 @@ class Auth {
|
||||
const absPermissions = userinfo[absPermissionsClaim]
|
||||
if (!absPermissions) throw new Error(`Advanced permissions claim ${absPermissionsClaim} not found in userinfo`)
|
||||
|
||||
if (user.updatePermissionsFromExternalJSON(absPermissions)) {
|
||||
if (await user.updatePermissionsFromExternalJSON(absPermissions)) {
|
||||
Logger.info(`[Auth] openid callback: Updating advanced perms for user "${user.username}" using "${JSON.stringify(absPermissions)}"`)
|
||||
await Database.userModel.updateFromOld(user)
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,7 +922,7 @@ class Auth {
|
||||
async userChangePassword(req, res) {
|
||||
let { password, newPassword } = req.body
|
||||
newPassword = newPassword || ''
|
||||
const matchingUser = req.userNew
|
||||
const matchingUser = req.user
|
||||
|
||||
// Only root can have an empty password
|
||||
if (matchingUser.type !== 'root' && !newPassword) {
|
||||
|
@ -91,8 +91,6 @@ class Server {
|
||||
|
||||
/**
|
||||
* Middleware to check if the current request is authenticated
|
||||
* req.user is set if authenticated to the OLD user object
|
||||
* req.userNew is set if authenticated to the NEW user object
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
@ -100,14 +98,7 @@ class Server {
|
||||
*/
|
||||
authMiddleware(req, res, next) {
|
||||
// ask passportjs if the current request is authenticated
|
||||
this.auth.isAuthenticated(req, res, () => {
|
||||
if (req.user) {
|
||||
// TODO: req.userNew to become req.user
|
||||
req.userNew = req.user
|
||||
req.user = Database.userModel.getOldUser(req.user)
|
||||
}
|
||||
next()
|
||||
})
|
||||
this.auth.isAuthenticated(req, res, next)
|
||||
}
|
||||
|
||||
cancelLibraryScan(libraryId) {
|
||||
|
@ -24,7 +24,7 @@ class AuthorController {
|
||||
|
||||
// Used on author landing page to include library items and items grouped in series
|
||||
if (include.includes('items')) {
|
||||
authorJson.libraryItems = await Database.libraryItemModel.getForAuthor(req.author, req.userNew)
|
||||
authorJson.libraryItems = await Database.libraryItemModel.getForAuthor(req.author, req.user)
|
||||
|
||||
if (include.includes('series')) {
|
||||
const seriesMap = {}
|
||||
@ -222,8 +222,8 @@ class AuthorController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async uploadImage(req, res) {
|
||||
if (!req.userNew.canUpload) {
|
||||
Logger.warn(`User "${req.userNew.username}" attempted to upload an image without permission`)
|
||||
if (!req.user.canUpload) {
|
||||
Logger.warn(`User "${req.user.username}" attempted to upload an image without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
if (!req.body.url) {
|
||||
@ -362,11 +362,11 @@ class AuthorController {
|
||||
const author = await Database.authorModel.getOldById(req.params.id)
|
||||
if (!author) return res.sendStatus(404)
|
||||
|
||||
if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[AuthorController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[AuthorController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[AuthorController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[AuthorController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -113,8 +113,8 @@ class BackupController {
|
||||
}
|
||||
|
||||
middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[BackupController] Non-admin user "${req.userNew.username}" attempting to access backups`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[BackupController] Non-admin user "${req.user.username}" attempting to access backups`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ class CacheController {
|
||||
|
||||
// POST: api/cache/purge
|
||||
async purgeCache(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
await CacheManager.purgeAll()
|
||||
@ -14,7 +14,7 @@ class CacheController {
|
||||
|
||||
// POST: api/cache/items/purge
|
||||
async purgeItemsCache(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
await CacheManager.purgeItems()
|
||||
|
@ -16,7 +16,7 @@ class CollectionController {
|
||||
*/
|
||||
async create(req, res) {
|
||||
const newCollection = new Collection()
|
||||
req.body.userId = req.userNew.id
|
||||
req.body.userId = req.user.id
|
||||
if (!newCollection.setData(req.body)) {
|
||||
return res.status(400).send('Invalid collection data')
|
||||
}
|
||||
@ -50,7 +50,7 @@ class CollectionController {
|
||||
}
|
||||
|
||||
async findAll(req, res) {
|
||||
const collectionsExpanded = await Database.collectionModel.getOldCollectionsJsonExpanded(req.userNew)
|
||||
const collectionsExpanded = await Database.collectionModel.getOldCollectionsJsonExpanded(req.user)
|
||||
res.json({
|
||||
collections: collectionsExpanded
|
||||
})
|
||||
@ -59,7 +59,7 @@ class CollectionController {
|
||||
async findOne(req, res) {
|
||||
const includeEntities = (req.query.include || '').split(',')
|
||||
|
||||
const collectionExpanded = await req.collection.getOldJsonExpanded(req.userNew, includeEntities)
|
||||
const collectionExpanded = await req.collection.getOldJsonExpanded(req.user, includeEntities)
|
||||
if (!collectionExpanded) {
|
||||
// This may happen if the user is restricted from all books
|
||||
return res.sendStatus(404)
|
||||
@ -334,11 +334,11 @@ class CollectionController {
|
||||
req.collection = collection
|
||||
}
|
||||
|
||||
if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[CollectionController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[CollectionController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[CollectionController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[CollectionController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,8 @@ class CustomMetadataProviderController {
|
||||
* @param {import('express').NextFunction} next
|
||||
*/
|
||||
async middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.warn(`[CustomMetadataProviderController] Non-admin user "${req.userNew.username}" attempted access route "${req.path}"`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.warn(`[CustomMetadataProviderController] Non-admin user "${req.user.username}" attempted access route "${req.path}"`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ class EmailController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async sendEBookToDevice(req, res) {
|
||||
Logger.debug(`[EmailController] Send ebook to device requested by user "${req.userNew.username}" for libraryItemId=${req.body.libraryItemId}, deviceName=${req.body.deviceName}`)
|
||||
Logger.debug(`[EmailController] Send ebook to device requested by user "${req.user.username}" for libraryItemId=${req.body.libraryItemId}, deviceName=${req.body.deviceName}`)
|
||||
|
||||
const device = Database.emailSettings.getEReaderDevice(req.body.deviceName)
|
||||
if (!device) {
|
||||
@ -67,7 +67,7 @@ class EmailController {
|
||||
}
|
||||
|
||||
// Check user has access to device
|
||||
if (!Database.emailSettings.checkUserCanAccessDevice(device, req.userNew)) {
|
||||
if (!Database.emailSettings.checkUserCanAccessDevice(device, req.user)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class EmailController {
|
||||
}
|
||||
|
||||
// Check user has access to library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(libraryItem)) {
|
||||
if (!req.user.checkCanAccessLibraryItem(libraryItem)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ class EmailController {
|
||||
}
|
||||
|
||||
adminMiddleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ class FileSystemController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async getPaths(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[FileSystemController] Non-admin user "${req.userNew.username}" attempting to get filesystem paths`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to get filesystem paths`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -69,8 +69,8 @@ class FileSystemController {
|
||||
|
||||
// POST: api/filesystem/pathexists
|
||||
async checkPathExists(req, res) {
|
||||
if (!req.userNew.canUpload) {
|
||||
Logger.error(`[FileSystemController] Non-admin user "${req.userNew.username}" attempting to check path exists`)
|
||||
if (!req.user.canUpload) {
|
||||
Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to check path exists`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class LibraryController {
|
||||
async findAll(req, res) {
|
||||
const libraries = await Database.libraryModel.getAllOldLibraries()
|
||||
|
||||
const librariesAccessible = req.userNew.permissions?.librariesAccessible || []
|
||||
const librariesAccessible = req.user.permissions?.librariesAccessible || []
|
||||
if (librariesAccessible.length) {
|
||||
return res.json({
|
||||
libraries: libraries.filter((lib) => librariesAccessible.includes(lib.id)).map((lib) => lib.toJSON())
|
||||
@ -110,7 +110,7 @@ class LibraryController {
|
||||
return res.json({
|
||||
filterdata,
|
||||
issues: filterdata.numIssues,
|
||||
numUserPlaylists: await Database.playlistModel.getNumPlaylistsForUserAndLibrary(req.userNew.id, req.library.id),
|
||||
numUserPlaylists: await Database.playlistModel.getNumPlaylistsForUserAndLibrary(req.user.id, req.library.id),
|
||||
customMetadataProviders,
|
||||
library: req.library
|
||||
})
|
||||
@ -327,9 +327,9 @@ class LibraryController {
|
||||
const filterByValue = filterByGroup ? libraryFilters.decode(payload.filterBy.replace(`${filterByGroup}.`, '')) : null
|
||||
if (filterByGroup === 'series' && filterByValue !== 'no-series' && payload.collapseseries) {
|
||||
const seriesId = libraryFilters.decode(payload.filterBy.split('.')[1])
|
||||
payload.results = await libraryHelpers.handleCollapseSubseries(payload, seriesId, req.userNew, req.library)
|
||||
payload.results = await libraryHelpers.handleCollapseSubseries(payload, seriesId, req.user, req.library)
|
||||
} else {
|
||||
const { libraryItems, count } = await Database.libraryItemModel.getByFilterAndSort(req.library, req.userNew, payload)
|
||||
const { libraryItems, count } = await Database.libraryItemModel.getByFilterAndSort(req.library, req.user, payload)
|
||||
payload.results = libraryItems
|
||||
payload.total = count
|
||||
}
|
||||
@ -420,7 +420,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
const offset = payload.page * payload.limit
|
||||
const { series, count } = await seriesFilters.getFilteredSeries(req.library, req.userNew, payload.filterBy, payload.sortBy, payload.sortDesc, include, payload.limit, offset)
|
||||
const { series, count } = await seriesFilters.getFilteredSeries(req.library, req.user, payload.filterBy, payload.sortBy, payload.sortDesc, include, payload.limit, offset)
|
||||
|
||||
payload.total = count
|
||||
payload.results = series
|
||||
@ -447,11 +447,11 @@ class LibraryController {
|
||||
if (!series) return res.sendStatus(404)
|
||||
const oldSeries = series.getOldSeries()
|
||||
|
||||
const libraryItemsInSeries = await libraryItemsBookFilters.getLibraryItemsForSeries(oldSeries, req.userNew)
|
||||
const libraryItemsInSeries = await libraryItemsBookFilters.getLibraryItemsForSeries(oldSeries, req.user)
|
||||
|
||||
const seriesJson = oldSeries.toJSON()
|
||||
if (include.includes('progress')) {
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter((li) => !!req.userNew.getMediaProgress(li.media.id)?.isFinished)
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter((li) => !!req.user.getMediaProgress(li.media.id)?.isFinished)
|
||||
seriesJson.progress = {
|
||||
libraryItemIds: libraryItemsInSeries.map((li) => li.id),
|
||||
libraryItemIdsFinished: libraryItemsFinished.map((li) => li.id),
|
||||
@ -492,7 +492,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
// TODO: Create paginated queries
|
||||
let collections = await Database.collectionModel.getOldCollectionsJsonExpanded(req.userNew, req.library.id, include)
|
||||
let collections = await Database.collectionModel.getOldCollectionsJsonExpanded(req.user, req.library.id, include)
|
||||
|
||||
payload.total = collections.length
|
||||
|
||||
@ -512,7 +512,7 @@ class LibraryController {
|
||||
* @param {*} res
|
||||
*/
|
||||
async getUserPlaylistsForLibrary(req, res) {
|
||||
let playlistsForUser = await Database.playlistModel.getOldPlaylistsForUserAndLibrary(req.userNew.id, req.library.id)
|
||||
let playlistsForUser = await Database.playlistModel.getOldPlaylistsForUserAndLibrary(req.user.id, req.library.id)
|
||||
|
||||
const payload = {
|
||||
results: [],
|
||||
@ -552,7 +552,7 @@ class LibraryController {
|
||||
.split(',')
|
||||
.map((v) => v.trim().toLowerCase())
|
||||
.filter((v) => !!v)
|
||||
const shelves = await Database.libraryItemModel.getPersonalizedShelves(req.library, req.userNew, include, limitPerShelf)
|
||||
const shelves = await Database.libraryItemModel.getPersonalizedShelves(req.library, req.user, include, limitPerShelf)
|
||||
res.json(shelves)
|
||||
}
|
||||
|
||||
@ -563,8 +563,8 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async reorder(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.userNew}" attempted to reorder libraries`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.user}" attempted to reorder libraries`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const libraries = await Database.libraryModel.getAllOldLibraries()
|
||||
@ -609,7 +609,7 @@ class LibraryController {
|
||||
const limit = req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 12
|
||||
const query = asciiOnlyToLowerCase(req.query.q.trim())
|
||||
|
||||
const matches = await libraryItemFilters.search(req.userNew, req.library, query, limit)
|
||||
const matches = await libraryItemFilters.search(req.user, req.library, query, limit)
|
||||
res.json(matches)
|
||||
}
|
||||
|
||||
@ -662,7 +662,7 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async getAuthors(req, res) {
|
||||
const { bookWhere, replacements } = libraryItemsBookFilters.getUserPermissionBookWhereQuery(req.userNew)
|
||||
const { bookWhere, replacements } = libraryItemsBookFilters.getUserPermissionBookWhereQuery(req.user)
|
||||
const authors = await Database.authorModel.findAll({
|
||||
where: {
|
||||
libraryId: req.library.id
|
||||
@ -672,7 +672,7 @@ class LibraryController {
|
||||
model: Database.bookModel,
|
||||
attributes: ['id', 'tags', 'explicit'],
|
||||
where: bookWhere,
|
||||
required: !req.userNew.isAdminOrUp, // Only show authors with 0 books for admin users or up
|
||||
required: !req.user.isAdminOrUp, // Only show authors with 0 books for admin users or up
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
@ -746,8 +746,8 @@ class LibraryController {
|
||||
* @param {*} res
|
||||
*/
|
||||
async updateNarrator(req, res) {
|
||||
if (!req.userNew.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.userNew.username}" attempted to update narrator`)
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.user.username}" attempted to update narrator`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -796,8 +796,8 @@ class LibraryController {
|
||||
* @param {*} res
|
||||
*/
|
||||
async removeNarrator(req, res) {
|
||||
if (!req.userNew.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.userNew.username}" attempted to remove narrator`)
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.user.username}" attempted to remove narrator`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -839,8 +839,8 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async matchAll(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-root user "${req.userNew.username}" attempted to match library items`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-root user "${req.user.username}" attempted to match library items`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
Scanner.matchLibraryItems(req.library)
|
||||
@ -856,8 +856,8 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async scan(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.userNew.username}" attempted to scan library`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.user.username}" attempted to scan library`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
res.sendStatus(200)
|
||||
@ -887,7 +887,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
const offset = payload.page * payload.limit
|
||||
payload.episodes = await libraryItemsPodcastFilters.getRecentEpisodes(req.userNew, req.library, payload.limit, offset)
|
||||
payload.episodes = await libraryItemsPodcastFilters.getRecentEpisodes(req.user, req.library, payload.limit, offset)
|
||||
res.json(payload)
|
||||
}
|
||||
|
||||
@ -898,7 +898,7 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async getOPMLFile(req, res) {
|
||||
const userPermissionPodcastWhere = libraryItemsPodcastFilters.getUserPermissionPodcastWhereQuery(req.userNew)
|
||||
const userPermissionPodcastWhere = libraryItemsPodcastFilters.getUserPermissionPodcastWhereQuery(req.user)
|
||||
const podcasts = await Database.podcastModel.findAll({
|
||||
attributes: ['id', 'feedURL', 'title', 'description', 'itunesPageURL', 'language'],
|
||||
where: userPermissionPodcastWhere.podcastWhere,
|
||||
@ -924,8 +924,8 @@ class LibraryController {
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async removeAllMetadataFiles(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.userNew.username}" attempted to remove all metadata files`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-admin user "${req.user.username}" attempted to remove all metadata files`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -974,8 +974,8 @@ class LibraryController {
|
||||
* @param {import('express').NextFunction} next
|
||||
*/
|
||||
async middleware(req, res, next) {
|
||||
if (!req.userNew.checkCanAccessLibrary(req.params.id)) {
|
||||
Logger.warn(`[LibraryController] Library ${req.params.id} not accessible to user ${req.userNew.username}`)
|
||||
if (!req.user.checkCanAccessLibrary(req.params.id)) {
|
||||
Logger.warn(`[LibraryController] Library ${req.params.id} not accessible to user ${req.user.username}`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,7 @@ const ShareManager = require('../managers/ShareManager')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -33,8 +32,8 @@ class LibraryItemController {
|
||||
* ?include=progress,rssfeed,downloads,share
|
||||
* ?expanded=1
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async findOne(req, res) {
|
||||
const includeEntities = (req.query.include || '').split(',')
|
||||
@ -44,7 +43,7 @@ class LibraryItemController {
|
||||
// Include users media progress
|
||||
if (includeEntities.includes('progress')) {
|
||||
var episodeId = req.query.episode || null
|
||||
item.userMediaProgress = req.userNew.getOldMediaProgress(item.id, episodeId)
|
||||
item.userMediaProgress = req.user.getOldMediaProgress(item.id, episodeId)
|
||||
}
|
||||
|
||||
if (includeEntities.includes('rssfeed')) {
|
||||
@ -52,7 +51,7 @@ class LibraryItemController {
|
||||
item.rssFeed = feedData?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
if (item.mediaType === 'book' && req.userNew.isAdminOrUp && includeEntities.includes('share')) {
|
||||
if (item.mediaType === 'book' && req.user.isAdminOrUp && includeEntities.includes('share')) {
|
||||
item.mediaItemShare = ShareManager.findByMediaItemId(item.media.id)
|
||||
}
|
||||
|
||||
@ -69,6 +68,11 @@ class LibraryItemController {
|
||||
res.json(req.libraryItem)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async update(req, res) {
|
||||
var libraryItem = req.libraryItem
|
||||
// Item has cover and update is removing cover so purge it from cache
|
||||
@ -91,8 +95,8 @@ class LibraryItemController {
|
||||
* Optional query params:
|
||||
* ?hard=1
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async delete(req, res) {
|
||||
const hardDelete = req.query.hard == 1 // Delete from file system
|
||||
@ -114,12 +118,12 @@ class LibraryItemController {
|
||||
* GET: /api/items/:id/download
|
||||
* Download library item. Zip file if multiple files.
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
download(req, res) {
|
||||
if (!req.userNew.canDownload) {
|
||||
Logger.warn(`User "${req.userNew.username}" attempted to download without permission`)
|
||||
if (!req.user.canDownload) {
|
||||
Logger.warn(`User "${req.user.username}" attempted to download without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const libraryItemPath = req.libraryItem.path
|
||||
@ -132,12 +136,12 @@ class LibraryItemController {
|
||||
if (audioMimeType) {
|
||||
res.setHeader('Content-Type', audioMimeType)
|
||||
}
|
||||
Logger.info(`[LibraryItemController] User "${req.userNew.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
||||
res.download(libraryItemPath, req.libraryItem.relPath)
|
||||
return
|
||||
}
|
||||
|
||||
Logger.info(`[LibraryItemController] User "${req.userNew.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${itemTitle}" at "${libraryItemPath}"`)
|
||||
const filename = `${itemTitle}.zip`
|
||||
zipHelpers.zipDirectoryPipe(libraryItemPath, filename, res)
|
||||
}
|
||||
@ -146,8 +150,8 @@ class LibraryItemController {
|
||||
* PATCH: /items/:id/media
|
||||
* Update media for a library item. Will create new authors & series when necessary
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateMedia(req, res) {
|
||||
const libraryItem = req.libraryItem
|
||||
@ -207,10 +211,16 @@ class LibraryItemController {
|
||||
})
|
||||
}
|
||||
|
||||
// POST: api/items/:id/cover
|
||||
/**
|
||||
* POST: /api/items/:id/cover
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
* @param {boolean} [updateAndReturnJson=true]
|
||||
*/
|
||||
async uploadCover(req, res, updateAndReturnJson = true) {
|
||||
if (!req.userNew.canUpload) {
|
||||
Logger.warn(`User "${req.userNew.username}" attempted to upload a cover without permission`)
|
||||
if (!req.user.canUpload) {
|
||||
Logger.warn(`User "${req.user.username}" attempted to upload a cover without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -243,7 +253,12 @@ class LibraryItemController {
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH: api/items/:id/cover
|
||||
/**
|
||||
* PATCH: /api/items/:id/cover
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateCover(req, res) {
|
||||
const libraryItem = req.libraryItem
|
||||
if (!req.body.cover) {
|
||||
@ -264,7 +279,12 @@ class LibraryItemController {
|
||||
})
|
||||
}
|
||||
|
||||
// DELETE: api/items/:id/cover
|
||||
/**
|
||||
* DELETE: /api/items/:id/cover
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async removeCover(req, res) {
|
||||
var libraryItem = req.libraryItem
|
||||
|
||||
@ -279,10 +299,10 @@ class LibraryItemController {
|
||||
}
|
||||
|
||||
/**
|
||||
* GET: api/items/:id/cover
|
||||
* GET: /api/items/:id/cover
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getCover(req, res) {
|
||||
const {
|
||||
@ -308,7 +328,7 @@ class LibraryItemController {
|
||||
}
|
||||
|
||||
// Check if user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(libraryItem)) {
|
||||
if (!req.user.checkCanAccessLibraryItem(libraryItem)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -377,7 +397,12 @@ class LibraryItemController {
|
||||
this.playbackSessionManager.startSessionRequest(req, res, episodeId)
|
||||
}
|
||||
|
||||
// PATCH: api/items/:id/tracks
|
||||
/**
|
||||
* PATCH: /api/items/:id/tracks
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateTracks(req, res) {
|
||||
var libraryItem = req.libraryItem
|
||||
var orderedFileData = req.body.orderedFileData
|
||||
@ -391,7 +416,12 @@ class LibraryItemController {
|
||||
res.json(libraryItem.toJSON())
|
||||
}
|
||||
|
||||
// POST api/items/:id/match
|
||||
/**
|
||||
* POST /api/items/:id/match
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async match(req, res) {
|
||||
var libraryItem = req.libraryItem
|
||||
|
||||
@ -406,12 +436,12 @@ class LibraryItemController {
|
||||
* Optional query params:
|
||||
* ?hard=1
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchDelete(req, res) {
|
||||
if (!req.userNew.canDelete) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (!req.user.canDelete) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const hardDelete = req.query.hard == 1 // Delete files from filesystem
|
||||
@ -447,7 +477,12 @@ class LibraryItemController {
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
// POST: api/items/batch/update
|
||||
/**
|
||||
* POST: /api/items/batch/update
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchUpdate(req, res) {
|
||||
const updatePayloads = req.body
|
||||
if (!updatePayloads?.length) {
|
||||
@ -493,7 +528,12 @@ class LibraryItemController {
|
||||
})
|
||||
}
|
||||
|
||||
// POST: api/items/batch/get
|
||||
/**
|
||||
* POST: /api/items/batch/get
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchGet(req, res) {
|
||||
const libraryItemIds = req.body.libraryItemIds || []
|
||||
if (!libraryItemIds.length) {
|
||||
@ -507,10 +547,15 @@ class LibraryItemController {
|
||||
})
|
||||
}
|
||||
|
||||
// POST: api/items/batch/quickmatch
|
||||
/**
|
||||
* POST: /api/items/batch/quickmatch
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchQuickMatch(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.warn(`Non-admin user "${req.userNew.username}" other than admin attempted to batch quick match library items`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.warn(`Non-admin user "${req.user.username}" other than admin attempted to batch quick match library items`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -545,13 +590,18 @@ class LibraryItemController {
|
||||
updates: itemsUpdated,
|
||||
unmatched: itemsUnmatched
|
||||
}
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'batch_quickmatch_complete', result)
|
||||
SocketAuthority.clientEmitter(req.user.id, 'batch_quickmatch_complete', result)
|
||||
}
|
||||
|
||||
// POST: api/items/batch/scan
|
||||
/**
|
||||
* POST: /api/items/batch/scan
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchScan(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.warn(`Non-admin user "${req.userNew.username}" other than admin attempted to batch scan library items`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.warn(`Non-admin user "${req.user.username}" other than admin attempted to batch scan library items`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -583,10 +633,15 @@ class LibraryItemController {
|
||||
await Database.resetLibraryIssuesFilterData(libraryId)
|
||||
}
|
||||
|
||||
// POST: api/items/:id/scan
|
||||
/**
|
||||
* POST: /api/items/:id/scan
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async scan(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.userNew.username}" attempted to scan library item`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.user.username}" attempted to scan library item`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -602,9 +657,15 @@ class LibraryItemController {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* GET: /api/items/:id/metadata-object
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
getMetadataObject(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.userNew.username}" attempted to get metadata object`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.user.username}" attempted to get metadata object`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -616,10 +677,15 @@ class LibraryItemController {
|
||||
res.json(this.audioMetadataManager.getMetadataObjectForApi(req.libraryItem))
|
||||
}
|
||||
|
||||
// POST: api/items/:id/chapters
|
||||
/**
|
||||
* POST: /api/items/:id/chapters
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateMediaChapters(req, res) {
|
||||
if (!req.userNew.canUpdate) {
|
||||
Logger.error(`[LibraryItemController] User "${req.userNew.username}" attempted to update chapters with invalid permissions`)
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.error(`[LibraryItemController] User "${req.user.username}" attempted to update chapters with invalid permissions`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -647,15 +713,15 @@ class LibraryItemController {
|
||||
}
|
||||
|
||||
/**
|
||||
* GET api/items/:id/ffprobe/:fileid
|
||||
* GET: /api/items/:id/ffprobe/:fileid
|
||||
* FFProbe JSON result from audio file
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getFFprobeData(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.userNew.username}" attempted to get ffprobe data`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-admin user "${req.user.username}" attempted to get ffprobe data`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
if (req.libraryFile.fileType !== 'audio') {
|
||||
@ -676,8 +742,8 @@ class LibraryItemController {
|
||||
/**
|
||||
* GET api/items/:id/file/:fileid
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getLibraryFile(req, res) {
|
||||
const libraryFile = req.libraryFile
|
||||
@ -699,13 +765,13 @@ class LibraryItemController {
|
||||
/**
|
||||
* DELETE api/items/:id/file/:fileid
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async deleteLibraryFile(req, res) {
|
||||
const libraryFile = req.libraryFile
|
||||
|
||||
Logger.info(`[LibraryItemController] User "${req.userNew.username}" requested file delete at "${libraryFile.metadata.path}"`)
|
||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested file delete at "${libraryFile.metadata.path}"`)
|
||||
|
||||
await fs.remove(libraryFile.metadata.path).catch((error) => {
|
||||
Logger.error(`[LibraryItemController] Failed to delete library file at "${libraryFile.metadata.path}"`, error)
|
||||
@ -727,18 +793,19 @@ class LibraryItemController {
|
||||
/**
|
||||
* GET api/items/:id/file/:fileid/download
|
||||
* Same as GET api/items/:id/file/:fileid but allows logging and restricting downloads
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
*
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async downloadLibraryFile(req, res) {
|
||||
const libraryFile = req.libraryFile
|
||||
|
||||
if (!req.userNew.canDownload) {
|
||||
Logger.error(`[LibraryItemController] User "${req.userNew.username}" without download permission attempted to download file "${libraryFile.metadata.path}"`)
|
||||
if (!req.user.canDownload) {
|
||||
Logger.error(`[LibraryItemController] User "${req.user.username}" without download permission attempted to download file "${libraryFile.metadata.path}"`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
Logger.info(`[LibraryItemController] User "${req.userNew.username}" requested download for item "${req.libraryItem.media.metadata.title}" file at "${libraryFile.metadata.path}"`)
|
||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${req.libraryItem.media.metadata.title}" file at "${libraryFile.metadata.path}"`)
|
||||
|
||||
if (global.XAccel) {
|
||||
const encodedURI = encodeUriPath(global.XAccel + libraryFile.metadata.path)
|
||||
@ -761,8 +828,8 @@ class LibraryItemController {
|
||||
* fileid is only required when reading a supplementary ebook
|
||||
* when no fileid is passed in the primary ebook will be returned
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getEBookFile(req, res) {
|
||||
let ebookFile = null
|
||||
@ -782,7 +849,7 @@ class LibraryItemController {
|
||||
}
|
||||
const ebookFilePath = ebookFile.metadata.path
|
||||
|
||||
Logger.info(`[LibraryItemController] User "${req.userNew.username}" requested download for item "${req.libraryItem.media.metadata.title}" ebook at "${ebookFilePath}"`)
|
||||
Logger.info(`[LibraryItemController] User "${req.user.username}" requested download for item "${req.libraryItem.media.metadata.title}" ebook at "${ebookFilePath}"`)
|
||||
|
||||
if (global.XAccel) {
|
||||
const encodedURI = encodeUriPath(global.XAccel + ebookFilePath)
|
||||
@ -799,8 +866,8 @@ class LibraryItemController {
|
||||
* if an ebook file is the primary ebook, then it will be changed to supplementary
|
||||
* if an ebook file is supplementary, then it will be changed to primary
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateEbookFileStatus(req, res) {
|
||||
const ebookLibraryFile = req.libraryItem.libraryFiles.find((lf) => lf.ino === req.params.fileid)
|
||||
@ -826,16 +893,16 @@ class LibraryItemController {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
* @param {import('express').NextFunction} next
|
||||
* @param {RequestWithUser} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async middleware(req, res, next) {
|
||||
req.libraryItem = await Database.libraryItemModel.getOldById(req.params.id)
|
||||
if (!req.libraryItem?.media) return res.sendStatus(404)
|
||||
|
||||
// Check user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(req.libraryItem)) {
|
||||
if (!req.user.checkCanAccessLibraryItem(req.libraryItem)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -850,11 +917,11 @@ class LibraryItemController {
|
||||
|
||||
if (req.path.includes('/play')) {
|
||||
// allow POST requests using /play and /play/:episodeId
|
||||
} else if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
} else if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[LibraryItemController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,7 @@ const userStats = require('../utils/queries/userStats')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -24,7 +23,7 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
getCurrentUser(req, res) {
|
||||
res.json(req.userNew.toOldJSONForBrowser())
|
||||
res.json(req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,7 +35,7 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getListeningSessions(req, res) {
|
||||
const listeningSessions = await this.getUserListeningSessionsHelper(req.userNew.id)
|
||||
const listeningSessions = await this.getUserListeningSessionsHelper(req.user.id)
|
||||
|
||||
const itemsPerPage = toNumber(req.query.itemsPerPage, 10) || 10
|
||||
const page = toNumber(req.query.page, 0)
|
||||
@ -73,7 +72,7 @@ class MeController {
|
||||
}
|
||||
|
||||
const mediaItemId = episode?.id || libraryItem.mediaId
|
||||
let listeningSessions = await this.getUserItemListeningSessionsHelper(req.userNew.id, mediaItemId)
|
||||
let listeningSessions = await this.getUserItemListeningSessionsHelper(req.user.id, mediaItemId)
|
||||
|
||||
const itemsPerPage = toNumber(req.query.itemsPerPage, 10) || 10
|
||||
const page = toNumber(req.query.page, 0)
|
||||
@ -101,7 +100,7 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getListeningStats(req, res) {
|
||||
const listeningStats = await this.getUserListeningStatsHelpers(req.userNew.id)
|
||||
const listeningStats = await this.getUserListeningStatsHelpers(req.user.id)
|
||||
res.json(listeningStats)
|
||||
}
|
||||
|
||||
@ -112,7 +111,7 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getMediaProgress(req, res) {
|
||||
const mediaProgress = req.userNew.getOldMediaProgress(req.params.id, req.params.episodeId || null)
|
||||
const mediaProgress = req.user.getOldMediaProgress(req.params.id, req.params.episodeId || null)
|
||||
if (!mediaProgress) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
@ -127,9 +126,9 @@ class MeController {
|
||||
*/
|
||||
async removeMediaProgress(req, res) {
|
||||
await Database.mediaProgressModel.removeById(req.params.id)
|
||||
req.userNew.mediaProgresses = req.userNew.mediaProgresses.filter((mp) => mp.id !== req.params.id)
|
||||
req.user.mediaProgresses = req.user.mediaProgresses.filter((mp) => mp.id !== req.params.id)
|
||||
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
@ -146,12 +145,12 @@ class MeController {
|
||||
libraryItemId: req.params.libraryItemId,
|
||||
episodeId: req.params.episodeId
|
||||
}
|
||||
const mediaProgressResponse = await req.userNew.createUpdateMediaProgressFromPayload(progressUpdatePayload)
|
||||
const mediaProgressResponse = await req.user.createUpdateMediaProgressFromPayload(progressUpdatePayload)
|
||||
if (mediaProgressResponse.error) {
|
||||
return res.status(mediaProgressResponse.statusCode || 400).send(mediaProgressResponse.error)
|
||||
}
|
||||
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
@ -170,7 +169,7 @@ class MeController {
|
||||
|
||||
let hasUpdated = false
|
||||
for (const itemProgress of itemProgressPayloads) {
|
||||
const mediaProgressResponse = await req.userNew.createUpdateMediaProgressFromPayload(itemProgress)
|
||||
const mediaProgressResponse = await req.user.createUpdateMediaProgressFromPayload(itemProgress)
|
||||
if (mediaProgressResponse.error) {
|
||||
Logger.error(`[MeController] batchUpdateMediaProgress: ${mediaProgressResponse.error}`)
|
||||
continue
|
||||
@ -180,7 +179,7 @@ class MeController {
|
||||
}
|
||||
|
||||
if (hasUpdated) {
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
res.sendStatus(200)
|
||||
@ -205,8 +204,8 @@ class MeController {
|
||||
return res.status(400).send('Invalid title')
|
||||
}
|
||||
|
||||
const bookmark = await req.userNew.createBookmark(req.params.id, time, title)
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
const bookmark = await req.user.createBookmark(req.params.id, time, title)
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
res.json(bookmark)
|
||||
}
|
||||
|
||||
@ -229,13 +228,13 @@ class MeController {
|
||||
return res.status(400).send('Invalid title')
|
||||
}
|
||||
|
||||
const bookmark = await req.userNew.updateBookmark(req.params.id, time, title)
|
||||
const bookmark = await req.user.updateBookmark(req.params.id, time, title)
|
||||
if (!bookmark) {
|
||||
Logger.error(`[MeController] updateBookmark not found for library item id "${req.params.id}" and time "${time}"`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
res.json(bookmark)
|
||||
}
|
||||
|
||||
@ -253,14 +252,14 @@ class MeController {
|
||||
return res.status(400).send('Invalid time')
|
||||
}
|
||||
|
||||
if (!req.userNew.findBookmark(req.params.id, time)) {
|
||||
if (!req.user.findBookmark(req.params.id, time)) {
|
||||
Logger.error(`[MeController] removeBookmark not found`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
await req.userNew.removeBookmark(req.params.id, time)
|
||||
await req.user.removeBookmark(req.params.id, time)
|
||||
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
@ -275,8 +274,8 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
updatePassword(req, res) {
|
||||
if (req.userNew.isGuest) {
|
||||
Logger.error(`[MeController] Guest user "${req.userNew.username}" attempted to change password`)
|
||||
if (req.user.isGuest) {
|
||||
Logger.error(`[MeController] Guest user "${req.user.username}" attempted to change password`)
|
||||
return res.sendStatus(500)
|
||||
}
|
||||
this.auth.userChangePassword(req, res)
|
||||
@ -294,7 +293,7 @@ class MeController {
|
||||
async getAllLibraryItemsInProgress(req, res) {
|
||||
const limit = !isNaN(req.query.limit) ? Number(req.query.limit) || 25 : 25
|
||||
|
||||
const mediaProgressesInProgress = req.userNew.mediaProgresses.filter((mp) => !mp.isFinished && (mp.currentTime > 0 || mp.ebookProgress > 0))
|
||||
const mediaProgressesInProgress = req.user.mediaProgresses.filter((mp) => !mp.isFinished && (mp.currentTime > 0 || mp.ebookProgress > 0))
|
||||
|
||||
const libraryItemsIds = [...new Set(mediaProgressesInProgress.map((mp) => mp.extraData?.libraryItemId).filter((id) => id))]
|
||||
const libraryItems = await Database.libraryItemModel.getAllOldLibraryItems({ id: libraryItemsIds })
|
||||
@ -344,11 +343,11 @@ class MeController {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
const hasUpdated = await req.userNew.addSeriesToHideFromContinueListening(req.params.id)
|
||||
const hasUpdated = await req.user.addSeriesToHideFromContinueListening(req.params.id)
|
||||
if (hasUpdated) {
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
}
|
||||
res.json(req.userNew.toOldJSONForBrowser())
|
||||
res.json(req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -363,11 +362,11 @@ class MeController {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
const hasUpdated = await req.userNew.removeSeriesFromHideFromContinueListening(req.params.id)
|
||||
const hasUpdated = await req.user.removeSeriesFromHideFromContinueListening(req.params.id)
|
||||
if (hasUpdated) {
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
}
|
||||
res.json(req.userNew.toOldJSONForBrowser())
|
||||
res.json(req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -377,22 +376,22 @@ class MeController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async removeItemFromContinueListening(req, res) {
|
||||
const mediaProgress = req.userNew.mediaProgresses.find((mp) => mp.id === req.params.id)
|
||||
const mediaProgress = req.user.mediaProgresses.find((mp) => mp.id === req.params.id)
|
||||
if (!mediaProgress) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
// Already hidden
|
||||
if (mediaProgress.hideFromContinueListening) {
|
||||
return res.json(req.userNew.toOldJSONForBrowser())
|
||||
return res.json(req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
mediaProgress.hideFromContinueListening = true
|
||||
await mediaProgress.save()
|
||||
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.userNew.toOldJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.user.toOldJSONForBrowser())
|
||||
|
||||
res.json(req.userNew.toOldJSONForBrowser())
|
||||
res.json(req.user.toOldJSONForBrowser())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,7 +406,7 @@ class MeController {
|
||||
Logger.error(`[MeController] Invalid year "${year}"`)
|
||||
return res.status(400).send('Invalid year')
|
||||
}
|
||||
const data = await userStats.getStatsForYear(req.userNew.id, year)
|
||||
const data = await userStats.getStatsForYear(req.user.id, year)
|
||||
res.json(data)
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,7 @@ const adminStats = require('../utils/queries/adminStats')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -33,8 +32,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async handleUpload(req, res) {
|
||||
if (!req.userNew.canUpload) {
|
||||
Logger.warn(`User "${req.userNew.username}" attempted to upload without permission`)
|
||||
if (!req.user.canUpload) {
|
||||
Logger.warn(`User "${req.user.username}" attempted to upload without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
if (!req.files) {
|
||||
@ -118,8 +117,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateServerSettings(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`User "${req.userNew.username}" other than admin attempting to update server settings`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`User "${req.user.username}" other than admin attempting to update server settings`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const settingsUpdate = req.body
|
||||
@ -149,8 +148,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateSortingPrefixes(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`User "${req.userNew.username}" other than admin attempting to update server sorting prefixes`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`User "${req.user.username}" other than admin attempting to update server sorting prefixes`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
let sortingPrefixes = req.body.sortingPrefixes
|
||||
@ -249,7 +248,7 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async authorize(req, res) {
|
||||
const userResponse = await this.auth.getUserLoginResponsePayload(req.userNew)
|
||||
const userResponse = await this.auth.getUserLoginResponsePayload(req.user)
|
||||
res.json(userResponse)
|
||||
}
|
||||
|
||||
@ -261,8 +260,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getAllTags(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to getAllTags`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to getAllTags`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -305,8 +304,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async renameTag(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to renameTag`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to renameTag`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -360,8 +359,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async deleteTag(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to deleteTag`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to deleteTag`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -400,8 +399,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getAllGenres(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to getAllGenres`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to getAllGenres`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const genres = []
|
||||
@ -443,8 +442,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async renameGenre(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to renameGenre`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to renameGenre`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -498,8 +497,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async deleteGenre(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to deleteGenre`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to deleteGenre`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -543,8 +542,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
updateWatchedPath(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to updateWatchedPath`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to updateWatchedPath`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -601,8 +600,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
getAuthSettings(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to get auth settings`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to get auth settings`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
return res.json(Database.serverSettings.authenticationSettings)
|
||||
@ -616,8 +615,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async updateAuthSettings(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to update auth settings`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to update auth settings`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -721,8 +720,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getAdminStatsForYear(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to get admin stats for year`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to get admin stats for year`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const year = Number(req.params.year)
|
||||
@ -742,8 +741,8 @@ class MiscController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getLoggerData(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.userNew.username}" attempted to get logger data`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[MiscController] Non-admin user "${req.user.username}" attempted to get logger data`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,7 @@ const { version } = require('../../package.json')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -135,7 +134,7 @@ class NotificationController {
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@ const Playlist = require('../objects/Playlist')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -25,7 +24,7 @@ class PlaylistController {
|
||||
*/
|
||||
async create(req, res) {
|
||||
const oldPlaylist = new Playlist()
|
||||
req.body.userId = req.userNew.id
|
||||
req.body.userId = req.user.id
|
||||
const success = oldPlaylist.setData(req.body)
|
||||
if (!success) {
|
||||
return res.status(400).send('Invalid playlist request data')
|
||||
@ -75,7 +74,7 @@ class PlaylistController {
|
||||
async findAllForUser(req, res) {
|
||||
const playlistsForUser = await Database.playlistModel.findAll({
|
||||
where: {
|
||||
userId: req.userNew.id
|
||||
userId: req.user.id
|
||||
}
|
||||
})
|
||||
const playlists = []
|
||||
@ -415,7 +414,7 @@ class PlaylistController {
|
||||
return res.status(404).send('Collection not found')
|
||||
}
|
||||
// Expand collection to get library items
|
||||
const collectionExpanded = await collection.getOldJsonExpanded(req.userNew)
|
||||
const collectionExpanded = await collection.getOldJsonExpanded(req.user)
|
||||
if (!collectionExpanded) {
|
||||
// This can happen if the user has no access to all items in collection
|
||||
return res.status(404).send('Collection not found')
|
||||
@ -428,7 +427,7 @@ class PlaylistController {
|
||||
|
||||
const oldPlaylist = new Playlist()
|
||||
oldPlaylist.setData({
|
||||
userId: req.userNew.id,
|
||||
userId: req.user.id,
|
||||
libraryId: collection.libraryId,
|
||||
name: collection.name,
|
||||
description: collection.description || null
|
||||
@ -467,8 +466,8 @@ class PlaylistController {
|
||||
if (!playlist) {
|
||||
return res.status(404).send('Playlist not found')
|
||||
}
|
||||
if (playlist.userId !== req.userNew.id) {
|
||||
Logger.warn(`[PlaylistController] Playlist ${req.params.id} requested by user ${req.userNew.id} that is not the owner`)
|
||||
if (playlist.userId !== req.user.id) {
|
||||
Logger.warn(`[PlaylistController] Playlist ${req.params.id} requested by user ${req.user.id} that is not the owner`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
req.playlist = playlist
|
||||
|
@ -16,8 +16,7 @@ const LibraryItem = require('../objects/LibraryItem')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -33,8 +32,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async create(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to create podcast`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to create podcast`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const payload = req.body
|
||||
@ -134,8 +133,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getPodcastFeed(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to get podcast feed`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to get podcast feed`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -160,8 +159,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getFeedsFromOPMLText(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to get feeds from opml`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to get feeds from opml`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -183,8 +182,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async bulkCreatePodcastsFromOpmlFeedUrls(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to bulk create podcasts`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to bulk create podcasts`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -218,8 +217,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async checkNewEpisodes(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to check/download episodes`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to check/download episodes`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -246,8 +245,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
clearEpisodeDownloadQueue(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempting to clear download queue`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempting to clear download queue`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
this.podcastManager.clearDownloadQueue(req.params.id)
|
||||
@ -297,8 +296,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async downloadEpisodes(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to download episodes`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to download episodes`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
const libraryItem = req.libraryItem
|
||||
@ -320,8 +319,8 @@ class PodcastController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async quickMatchEpisodes(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.userNew.username}" attempted to download episodes`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to download episodes`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -469,15 +468,15 @@ class PodcastController {
|
||||
}
|
||||
|
||||
// Check user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(item)) {
|
||||
if (!req.user.checkCanAccessLibraryItem(item)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[PodcastController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[PodcastController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[PodcastController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[PodcastController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,7 @@ const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilter
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -45,8 +44,8 @@ class RSSFeedController {
|
||||
if (!item) return res.sendStatus(404)
|
||||
|
||||
// Check user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(item)) {
|
||||
Logger.error(`[RSSFeedController] User "${req.userNew.username}" attempted to open an RSS feed for item "${item.media.metadata.title}" that they don\'t have access to`)
|
||||
if (!req.user.checkCanAccessLibraryItem(item)) {
|
||||
Logger.error(`[RSSFeedController] User "${req.user.username}" attempted to open an RSS feed for item "${item.media.metadata.title}" that they don\'t have access to`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -68,7 +67,7 @@ class RSSFeedController {
|
||||
return res.status(400).send('Slug already in use')
|
||||
}
|
||||
|
||||
const feed = await this.rssFeedManager.openFeedForItem(req.userNew.id, item, req.body)
|
||||
const feed = await this.rssFeedManager.openFeedForItem(req.user.id, item, req.body)
|
||||
res.json({
|
||||
feed: feed.toJSONMinified()
|
||||
})
|
||||
@ -109,7 +108,7 @@ class RSSFeedController {
|
||||
return res.status(400).send('Collection has no audio tracks')
|
||||
}
|
||||
|
||||
const feed = await this.rssFeedManager.openFeedForCollection(req.userNew.id, collectionExpanded, req.body)
|
||||
const feed = await this.rssFeedManager.openFeedForCollection(req.user.id, collectionExpanded, req.body)
|
||||
res.json({
|
||||
feed: feed.toJSONMinified()
|
||||
})
|
||||
@ -152,7 +151,7 @@ class RSSFeedController {
|
||||
return res.status(400).send('Series has no audio tracks')
|
||||
}
|
||||
|
||||
const feed = await this.rssFeedManager.openFeedForSeries(req.userNew.id, seriesJson, req.body)
|
||||
const feed = await this.rssFeedManager.openFeedForSeries(req.user.id, seriesJson, req.body)
|
||||
res.json({
|
||||
feed: feed.toJSONMinified()
|
||||
})
|
||||
@ -177,9 +176,9 @@ class RSSFeedController {
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
// Only admins can manage rss feeds
|
||||
Logger.error(`[RSSFeedController] Non-admin user "${req.userNew.username}" attempted to make a request to an RSS feed route`)
|
||||
Logger.error(`[RSSFeedController] Non-admin user "${req.user.username}" attempted to make a request to an RSS feed route`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,7 @@ const { isValidASIN } = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
|
@ -6,8 +6,7 @@ const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilter
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -37,7 +36,7 @@ class SeriesController {
|
||||
if (include.includes('progress')) {
|
||||
const libraryItemsInSeries = req.libraryItemsInSeries
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter((li) => {
|
||||
return req.userNew.getMediaProgress(li.media.id)?.isFinished
|
||||
return req.user.getMediaProgress(li.media.id)?.isFinished
|
||||
})
|
||||
seriesJson.progress = {
|
||||
libraryItemIds: libraryItemsInSeries.map((li) => li.id),
|
||||
@ -81,17 +80,17 @@ class SeriesController {
|
||||
/**
|
||||
* Filter out any library items not accessible to user
|
||||
*/
|
||||
const libraryItems = await libraryItemsBookFilters.getLibraryItemsForSeries(series, req.userNew)
|
||||
const libraryItems = await libraryItemsBookFilters.getLibraryItemsForSeries(series, req.user)
|
||||
if (!libraryItems.length) {
|
||||
Logger.warn(`[SeriesController] User "${req.userNew.username}" attempted to access series "${series.id}" with no accessible books`)
|
||||
Logger.warn(`[SeriesController] User "${req.user.username}" attempted to access series "${series.id}" with no accessible books`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[SeriesController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[SeriesController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[SeriesController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[SeriesController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@ const ShareManager = require('../managers/ShareManager')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -25,8 +24,8 @@ class SessionController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getAllWithUserData(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] getAllWithUserData: Non-admin user "${req.userNew.username}" requested all session data`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] getAllWithUserData: Non-admin user "${req.user.username}" requested all session data`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
// Validate "user" query
|
||||
@ -120,8 +119,8 @@ class SessionController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getOpenSessions(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] getOpenSessions: Non-admin user "${req.userNew.username}" requested open session data`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] getOpenSessions: Non-admin user "${req.user.username}" requested open session data`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
@ -164,7 +163,7 @@ class SessionController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
sync(req, res) {
|
||||
this.playbackSessionManager.syncSessionRequest(req.userNew, req.playbackSession, req.body, res)
|
||||
this.playbackSessionManager.syncSessionRequest(req.user, req.playbackSession, req.body, res)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +177,7 @@ class SessionController {
|
||||
close(req, res) {
|
||||
let syncData = req.body
|
||||
if (syncData && !Object.keys(syncData).length) syncData = null
|
||||
this.playbackSessionManager.closeSessionRequest(req.userNew, req.playbackSession, syncData, res)
|
||||
this.playbackSessionManager.closeSessionRequest(req.user, req.playbackSession, syncData, res)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,8 +210,8 @@ class SessionController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async batchDelete(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] Non-admin user "${req.userNew.username}" attempted to batch delete sessions`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[SessionController] Non-admin user "${req.user.username}" attempted to batch delete sessions`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
// Validate session ids
|
||||
@ -235,7 +234,7 @@ class SessionController {
|
||||
id: req.body.sessions
|
||||
}
|
||||
})
|
||||
Logger.info(`[SessionController] ${sessionsRemoved} playback sessions removed by "${req.userNew.username}"`)
|
||||
Logger.info(`[SessionController] ${sessionsRemoved} playback sessions removed by "${req.user.username}"`)
|
||||
res.sendStatus(200)
|
||||
} catch (error) {
|
||||
Logger.error(`[SessionController] Failed to remove playback sessions`, error)
|
||||
@ -277,8 +276,8 @@ class SessionController {
|
||||
var playbackSession = this.playbackSessionManager.getSession(req.params.id)
|
||||
if (!playbackSession) return res.sendStatus(404)
|
||||
|
||||
if (playbackSession.userId !== req.userNew.id) {
|
||||
Logger.error(`[SessionController] User "${req.userNew.username}" attempting to access session belonging to another user "${req.params.id}"`)
|
||||
if (playbackSession.userId !== req.user.id) {
|
||||
Logger.error(`[SessionController] User "${req.user.username}" attempting to access session belonging to another user "${req.params.id}"`)
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
@ -299,11 +298,11 @@ class SessionController {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
if (req.method == 'DELETE' && !req.userNew.canDelete) {
|
||||
Logger.warn(`[SessionController] User "${req.userNew.username}" attempted to delete without permission`)
|
||||
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||
Logger.warn(`[SessionController] User "${req.user.username}" attempted to delete without permission`)
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.userNew.canUpdate) {
|
||||
Logger.warn(`[SessionController] User "${req.userNew.username}" attempted to update without permission`)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||
Logger.warn(`[SessionController] User "${req.user.username}" attempted to update without permission`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,7 @@ const ShareManager = require('../managers/ShareManager')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -255,8 +254,8 @@ class ShareController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async createMediaItemShare(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[ShareController] Non-admin user "${req.userNew.username}" attempted to create item share`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[ShareController] Non-admin user "${req.user.username}" attempted to create item share`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -299,7 +298,7 @@ class ShareController {
|
||||
expiresAt: expiresAt || null,
|
||||
mediaItemId,
|
||||
mediaItemType,
|
||||
userId: req.userNew.id
|
||||
userId: req.user.id
|
||||
})
|
||||
|
||||
ShareManager.openMediaItemShare(mediaItemShare)
|
||||
@ -319,8 +318,8 @@ class ShareController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async deleteMediaItemShare(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[ShareController] Non-admin user "${req.userNew.username}" attempted to delete item share`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[ShareController] Non-admin user "${req.user.username}" attempted to delete item share`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,7 @@ const Database = require('../Database')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*/
|
||||
@ -39,7 +38,7 @@ class ToolsController {
|
||||
}
|
||||
|
||||
const options = req.query || {}
|
||||
this.abMergeManager.startAudiobookMerge(req.userNew.id, req.libraryItem, options)
|
||||
this.abMergeManager.startAudiobookMerge(req.user.id, req.libraryItem, options)
|
||||
|
||||
res.sendStatus(200)
|
||||
}
|
||||
@ -86,7 +85,7 @@ class ToolsController {
|
||||
forceEmbedChapters: req.query.forceEmbedChapters === '1',
|
||||
backup: req.query.backup === '1'
|
||||
}
|
||||
this.audioMetadataManager.updateMetadataForItem(req.userNew.id, req.libraryItem, options)
|
||||
this.audioMetadataManager.updateMetadataForItem(req.user.id, req.libraryItem, options)
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
@ -114,8 +113,8 @@ class ToolsController {
|
||||
}
|
||||
|
||||
// Check user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(libraryItem)) {
|
||||
Logger.error(`[ToolsController] Batch embed metadata library item (${libraryItemId}) not accessible to user "${req.userNew.username}"`)
|
||||
if (!req.user.checkCanAccessLibraryItem(libraryItem)) {
|
||||
Logger.error(`[ToolsController] Batch embed metadata library item (${libraryItemId}) not accessible to user "${req.user.username}"`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -136,7 +135,7 @@ class ToolsController {
|
||||
forceEmbedChapters: req.query.forceEmbedChapters === '1',
|
||||
backup: req.query.backup === '1'
|
||||
}
|
||||
this.audioMetadataManager.handleBatchEmbed(req.userNew.id, libraryItems, options)
|
||||
this.audioMetadataManager.handleBatchEmbed(req.user.id, libraryItems, options)
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
@ -147,8 +146,8 @@ class ToolsController {
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-root user "${req.userNew.username}" attempted to access tools route`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryItemController] Non-root user "${req.user.username}" attempted to access tools route`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -157,7 +156,7 @@ class ToolsController {
|
||||
if (!item?.media) return res.sendStatus(404)
|
||||
|
||||
// Check user can access this library item
|
||||
if (!req.userNew.checkCanAccessLibraryItem(item)) {
|
||||
if (!req.user.checkCanAccessLibraryItem(item)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -10,14 +10,12 @@ const { toNumber } = require('../utils/index')
|
||||
|
||||
/**
|
||||
* @typedef RequestUserObjects
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user
|
||||
* @property {import('../models/User')} user
|
||||
*
|
||||
* @typedef {Request & RequestUserObjects} RequestWithUser
|
||||
*
|
||||
* @typedef UserControllerRequestProps
|
||||
* @property {import('../models/User')} userNew
|
||||
* @property {import('../objects/user/User')} user - User that made the request
|
||||
* @property {import('../models/User')} user - User that made the request
|
||||
* @property {import('../objects/user/User')} [reqUser] - User for req param id
|
||||
*
|
||||
* @typedef {Request & UserControllerRequestProps} UserControllerRequest
|
||||
@ -32,8 +30,8 @@ class UserController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async findAll(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) return res.sendStatus(403)
|
||||
const hideRootToken = !req.userNew.isRoot
|
||||
if (!req.user.isAdminOrUp) return res.sendStatus(403)
|
||||
const hideRootToken = !req.user.isRoot
|
||||
|
||||
const includes = (req.query.include || '').split(',').map((i) => i.trim())
|
||||
|
||||
@ -62,8 +60,8 @@ class UserController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async findOne(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
Logger.error(`Non-admin user "${req.userNew.username}" attempted to get user`)
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`Non-admin user "${req.user.username}" attempted to get user`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -102,7 +100,7 @@ class UserController {
|
||||
return oldMediaProgress
|
||||
})
|
||||
|
||||
const userJson = req.reqUser.toJSONForBrowser(!req.userNew.isRoot)
|
||||
const userJson = req.reqUser.toJSONForBrowser(!req.user.isRoot)
|
||||
|
||||
userJson.mediaProgress = oldMediaProgresses
|
||||
|
||||
@ -155,8 +153,8 @@ class UserController {
|
||||
async update(req, res) {
|
||||
const user = req.reqUser
|
||||
|
||||
if (user.type === 'root' && !req.userNew.isRoot) {
|
||||
Logger.error(`[UserController] Admin user "${req.userNew.username}" attempted to update root user`)
|
||||
if (user.type === 'root' && !req.user.isRoot) {
|
||||
Logger.error(`[UserController] Admin user "${req.user.username}" attempted to update root user`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -184,7 +182,7 @@ class UserController {
|
||||
Logger.info(`[UserController] User ${user.username} was generated a new api token`)
|
||||
}
|
||||
await Database.updateUser(user)
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', user.toJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', user.toJSONForBrowser())
|
||||
}
|
||||
|
||||
res.json({
|
||||
@ -205,8 +203,8 @@ class UserController {
|
||||
Logger.error('[UserController] Attempt to delete root user. Root user cannot be deleted')
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
if (req.userNew.id === req.params.id) {
|
||||
Logger.error(`[UserController] User ${req.userNew.username} is attempting to delete self`)
|
||||
if (req.user.id === req.params.id) {
|
||||
Logger.error(`[UserController] User ${req.user.username} is attempting to delete self`)
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
const user = req.reqUser
|
||||
@ -241,7 +239,7 @@ class UserController {
|
||||
Logger.debug(`[UserController] Unlinking user "${req.reqUser.username}" from OpenID with sub "${req.reqUser.authOpenIDSub}"`)
|
||||
req.reqUser.authOpenIDSub = null
|
||||
if (await Database.userModel.updateFromOld(req.reqUser)) {
|
||||
SocketAuthority.clientEmitter(req.userNew.id, 'user_updated', req.reqUser.toJSONForBrowser())
|
||||
SocketAuthority.clientEmitter(req.user.id, 'user_updated', req.reqUser.toJSONForBrowser())
|
||||
res.sendStatus(200)
|
||||
} else {
|
||||
res.sendStatus(500)
|
||||
@ -296,7 +294,7 @@ class UserController {
|
||||
* @param {Response} res
|
||||
*/
|
||||
async getOnlineUsers(req, res) {
|
||||
if (!req.userNew.isAdminOrUp) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -313,9 +311,9 @@ class UserController {
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async middleware(req, res, next) {
|
||||
if (!req.userNew.isAdminOrUp && req.userNew.id !== req.params.id) {
|
||||
if (!req.user.isAdminOrUp && req.user.id !== req.params.id) {
|
||||
return res.sendStatus(403)
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST' || req.method == 'DELETE') && !req.userNew.isAdminOrUp) {
|
||||
} else if ((req.method == 'PATCH' || req.method == 'POST' || req.method == 'DELETE') && !req.user.isAdminOrUp) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class ApiCacheManager {
|
||||
Logger.debug(`[ApiCacheManager] Skipping cache for random sort`)
|
||||
return next()
|
||||
}
|
||||
const key = { user: req.userNew.username, url: req.url }
|
||||
const key = { user: req.user.username, url: req.url }
|
||||
const stringifiedKey = JSON.stringify(key)
|
||||
Logger.debug(`[ApiCacheManager] count: ${this.cache.size} size: ${this.cache.calculatedSize}`)
|
||||
const cached = this.cache.get(stringifiedKey)
|
||||
|
@ -48,7 +48,7 @@ class PlaybackSessionManager {
|
||||
const ip = requestIp.getClientIp(req)
|
||||
|
||||
const deviceInfo = new DeviceInfo()
|
||||
deviceInfo.setData(ip, ua, clientDeviceInfo, serverVersion, req.userNew?.id)
|
||||
deviceInfo.setData(ip, ua, clientDeviceInfo, serverVersion, req.user?.id)
|
||||
|
||||
if (clientDeviceInfo?.deviceId) {
|
||||
const existingDevice = await Database.getDeviceByDeviceId(clientDeviceInfo.deviceId)
|
||||
@ -75,7 +75,7 @@ class PlaybackSessionManager {
|
||||
const deviceInfo = await this.getDeviceInfo(req, req.body?.deviceInfo)
|
||||
Logger.debug(`[PlaybackSessionManager] startSessionRequest for device ${deviceInfo.deviceDescription}`)
|
||||
const { libraryItem, body: options } = req
|
||||
const session = await this.startSession(req.userNew, deviceInfo, libraryItem, episodeId, options)
|
||||
const session = await this.startSession(req.user, deviceInfo, libraryItem, episodeId, options)
|
||||
res.json(session.toJSONForClient(libraryItem))
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ class PlaybackSessionManager {
|
||||
|
||||
async syncLocalSessionsRequest(req, res) {
|
||||
const deviceInfo = await this.getDeviceInfo(req, req.body?.deviceInfo)
|
||||
const user = req.userNew
|
||||
const user = req.user
|
||||
const sessions = req.body.sessions || []
|
||||
|
||||
const syncResults = []
|
||||
@ -239,7 +239,7 @@ class PlaybackSessionManager {
|
||||
async syncLocalSessionRequest(req, res) {
|
||||
const deviceInfo = await this.getDeviceInfo(req, req.body?.deviceInfo)
|
||||
const sessionJson = req.body
|
||||
const result = await this.syncLocalSession(req.userNew, sessionJson, deviceInfo)
|
||||
const result = await this.syncLocalSession(req.user, sessionJson, deviceInfo)
|
||||
if (result.error) {
|
||||
res.status(500).send(result.error)
|
||||
} else {
|
||||
|
@ -2,7 +2,6 @@ const uuidv4 = require('uuid').v4
|
||||
const sequelize = require('sequelize')
|
||||
const Logger = require('../Logger')
|
||||
const oldUser = require('../objects/user/User')
|
||||
const AudioBookmark = require('../objects/user/AudioBookmark')
|
||||
const SocketAuthority = require('../SocketAuthority')
|
||||
const { isNullOrNaN } = require('../utils')
|
||||
|
||||
@ -52,6 +51,47 @@ class User extends Model {
|
||||
this.mediaProgresses
|
||||
}
|
||||
|
||||
/**
|
||||
* List of expected permission properties from the client
|
||||
* Only used for OpenID
|
||||
*/
|
||||
static permissionMapping = {
|
||||
canDownload: 'download',
|
||||
canUpload: 'upload',
|
||||
canDelete: 'delete',
|
||||
canUpdate: 'update',
|
||||
canAccessExplicitContent: 'accessExplicitContent',
|
||||
canAccessAllLibraries: 'accessAllLibraries',
|
||||
canAccessAllTags: 'accessAllTags',
|
||||
tagsAreDenylist: 'selectedTagsNotAccessible',
|
||||
// Direct mapping for array-based permissions
|
||||
allowedLibraries: 'librariesAccessible',
|
||||
allowedTags: 'itemTagsSelected'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sample to show how a JSON for updatePermissionsFromExternalJSON should look like
|
||||
* Only used for OpenID
|
||||
*
|
||||
* @returns {string} JSON string
|
||||
*/
|
||||
static getSampleAbsPermissions() {
|
||||
// Start with a template object where all permissions are false for simplicity
|
||||
const samplePermissions = Object.keys(User.permissionMapping).reduce((acc, key) => {
|
||||
// For array-based permissions, provide a sample array
|
||||
if (key === 'allowedLibraries') {
|
||||
acc[key] = [`5406ba8a-16e1-451d-96d7-4931b0a0d966`, `918fd848-7c1d-4a02-818a-847435a879ca`]
|
||||
} else if (key === 'allowedTags') {
|
||||
acc[key] = [`ExampleTag`, `AnotherTag`, `ThirdTag`]
|
||||
} else {
|
||||
acc[key] = false
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return JSON.stringify(samplePermissions, null, 2) // Pretty print the JSON
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} type
|
||||
@ -818,6 +858,69 @@ class User extends Model {
|
||||
await this.save()
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user permissions from external JSON
|
||||
*
|
||||
* @param {Object} absPermissions JSON containing user permissions
|
||||
* @returns {Promise<boolean>} true if updates were made
|
||||
*/
|
||||
async updatePermissionsFromExternalJSON(absPermissions) {
|
||||
if (!this.permissions) this.permissions = {}
|
||||
let hasUpdates = false
|
||||
|
||||
// Map the boolean permissions from absPermissions
|
||||
Object.keys(absPermissions).forEach((absKey) => {
|
||||
const userPermKey = User.permissionMapping[absKey]
|
||||
if (!userPermKey) {
|
||||
throw new Error(`Unexpected permission property: ${absKey}`)
|
||||
}
|
||||
|
||||
if (!['librariesAccessible', 'itemTagsSelected'].includes(userPermKey)) {
|
||||
if (this.permissions[userPermKey] !== !!absPermissions[absKey]) {
|
||||
this.permissions[userPermKey] = !!absPermissions[absKey]
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Handle allowedLibraries
|
||||
const librariesAccessible = this.permissions.librariesAccessible || []
|
||||
if (this.permissions.accessAllLibraries) {
|
||||
if (librariesAccessible.length) {
|
||||
this.permissions.librariesAccessible = []
|
||||
hasUpdates = true
|
||||
}
|
||||
} else if (absPermissions.allowedLibraries?.length && absPermissions.allowedLibraries.join(',') !== librariesAccessible.join(',')) {
|
||||
if (absPermissions.allowedLibraries.some((lid) => typeof lid !== 'string')) {
|
||||
throw new Error('Invalid permission property "allowedLibraries", expecting array of strings')
|
||||
}
|
||||
this.permissions.librariesAccessible = absPermissions.allowedLibraries
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
// Handle allowedTags
|
||||
const itemTagsSelected = this.permissions.itemTagsSelected || []
|
||||
if (this.permissions.accessAllTags) {
|
||||
if (itemTagsSelected.length) {
|
||||
this.permissions.itemTagsSelected = []
|
||||
hasUpdates = true
|
||||
}
|
||||
} else if (absPermissions.allowedTags?.length && absPermissions.allowedTags.join(',') !== itemTagsSelected.join(',')) {
|
||||
if (absPermissions.allowedTags.some((tag) => typeof tag !== 'string')) {
|
||||
throw new Error('Invalid permission property "allowedTags", expecting array of strings')
|
||||
}
|
||||
this.permissions.itemTagsSelected = absPermissions.allowedTags
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
if (hasUpdates) {
|
||||
this.changed('permissions', true)
|
||||
await this.save()
|
||||
}
|
||||
|
||||
return hasUpdates
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = User
|
||||
|
@ -2,7 +2,7 @@ const Path = require('path')
|
||||
const packageJson = require('../../../package.json')
|
||||
const { BookshelfView } = require('../../utils/constants')
|
||||
const Logger = require('../../Logger')
|
||||
const User = require('../user/User')
|
||||
const User = require('../../models/User')
|
||||
|
||||
class ServerSettings {
|
||||
constructor(settings) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
const Logger = require('../../Logger')
|
||||
const AudioBookmark = require('./AudioBookmark')
|
||||
const MediaProgress = require('./MediaProgress')
|
||||
|
||||
@ -268,109 +267,5 @@ class User {
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
// List of expected permission properties from the client
|
||||
static permissionMapping = {
|
||||
canDownload: 'download',
|
||||
canUpload: 'upload',
|
||||
canDelete: 'delete',
|
||||
canUpdate: 'update',
|
||||
canAccessExplicitContent: 'accessExplicitContent',
|
||||
canAccessAllLibraries: 'accessAllLibraries',
|
||||
canAccessAllTags: 'accessAllTags',
|
||||
tagsAreDenylist: 'selectedTagsNotAccessible',
|
||||
// Direct mapping for array-based permissions
|
||||
allowedLibraries: 'librariesAccessible',
|
||||
allowedTags: 'itemTagsSelected'
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user permissions from external JSON
|
||||
*
|
||||
* @param {Object} absPermissions JSON containing user permissions
|
||||
* @returns {boolean} true if updates were made
|
||||
*/
|
||||
updatePermissionsFromExternalJSON(absPermissions) {
|
||||
let hasUpdates = false
|
||||
let updatedUserPermissions = {}
|
||||
|
||||
// Initialize all permissions to false first
|
||||
Object.keys(User.permissionMapping).forEach((mappingKey) => {
|
||||
const userPermKey = User.permissionMapping[mappingKey]
|
||||
if (typeof this.permissions[userPermKey] === 'boolean') {
|
||||
updatedUserPermissions[userPermKey] = false // Default to false for boolean permissions
|
||||
}
|
||||
})
|
||||
|
||||
// Map the boolean permissions from absPermissions
|
||||
Object.keys(absPermissions).forEach((absKey) => {
|
||||
const userPermKey = User.permissionMapping[absKey]
|
||||
if (!userPermKey) {
|
||||
throw new Error(`Unexpected permission property: ${absKey}`)
|
||||
}
|
||||
|
||||
if (updatedUserPermissions[userPermKey] !== undefined) {
|
||||
updatedUserPermissions[userPermKey] = !!absPermissions[absKey]
|
||||
}
|
||||
})
|
||||
|
||||
// Update user permissions if changes were made
|
||||
if (JSON.stringify(this.permissions) !== JSON.stringify(updatedUserPermissions)) {
|
||||
this.permissions = updatedUserPermissions
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
// Handle allowedLibraries
|
||||
if (this.permissions.accessAllLibraries) {
|
||||
if (this.librariesAccessible.length) {
|
||||
this.librariesAccessible = []
|
||||
hasUpdates = true
|
||||
}
|
||||
} else if (absPermissions.allowedLibraries?.length && absPermissions.allowedLibraries.join(',') !== this.librariesAccessible.join(',')) {
|
||||
if (absPermissions.allowedLibraries.some((lid) => typeof lid !== 'string')) {
|
||||
throw new Error('Invalid permission property "allowedLibraries", expecting array of strings')
|
||||
}
|
||||
this.librariesAccessible = absPermissions.allowedLibraries
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
// Handle allowedTags
|
||||
if (this.permissions.accessAllTags) {
|
||||
if (this.itemTagsSelected.length) {
|
||||
this.itemTagsSelected = []
|
||||
hasUpdates = true
|
||||
}
|
||||
} else if (absPermissions.allowedTags?.length && absPermissions.allowedTags.join(',') !== this.itemTagsSelected.join(',')) {
|
||||
if (absPermissions.allowedTags.some((tag) => typeof tag !== 'string')) {
|
||||
throw new Error('Invalid permission property "allowedTags", expecting array of strings')
|
||||
}
|
||||
this.itemTagsSelected = absPermissions.allowedTags
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sample to show how a JSON for updatePermissionsFromExternalJSON should look like
|
||||
*
|
||||
* @returns {string} JSON string
|
||||
*/
|
||||
static getSampleAbsPermissions() {
|
||||
// Start with a template object where all permissions are false for simplicity
|
||||
const samplePermissions = Object.keys(User.permissionMapping).reduce((acc, key) => {
|
||||
// For array-based permissions, provide a sample array
|
||||
if (key === 'allowedLibraries') {
|
||||
acc[key] = [`5406ba8a-16e1-451d-96d7-4931b0a0d966`, `918fd848-7c1d-4a02-818a-847435a879ca`]
|
||||
} else if (key === 'allowedTags') {
|
||||
acc[key] = [`ExampleTag`, `AnotherTag`, `ThirdTag`]
|
||||
} else {
|
||||
acc[key] = false
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return JSON.stringify(samplePermissions, null, 2) // Pretty print the JSON
|
||||
}
|
||||
}
|
||||
module.exports = User
|
||||
|
@ -12,7 +12,7 @@ describe('ApiCacheManager', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cache = { get: sinon.stub(), set: sinon.spy() }
|
||||
req = { user: { username: 'testUser' }, userNew: { username: 'testUser' }, url: '/test-url', query: {} }
|
||||
req = { user: { username: 'testUser' }, url: '/test-url', query: {} }
|
||||
res = { send: sinon.spy(), getHeaders: sinon.stub(), statusCode: 200, status: sinon.spy(), set: sinon.spy() }
|
||||
next = sinon.spy()
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user