mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-09 21:39:37 +00:00
Adding permissions per user, add volume number sort
This commit is contained in:
parent
1d7d2a1dac
commit
ee452d41ee
18 changed files with 241 additions and 43 deletions
|
|
@ -89,6 +89,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async deleteAllAudiobooks(req, res) {
|
||||
if (!req.user.isRoot) {
|
||||
Logger.warn('User other than root attempted to delete all audiobooks', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
Logger.info('Removing all Audiobooks')
|
||||
var success = await this.db.recreateAudiobookDb()
|
||||
if (success) res.sendStatus(200)
|
||||
|
|
@ -130,6 +134,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async deleteAudiobook(req, res) {
|
||||
if (!req.user.canDelete) {
|
||||
Logger.warn('User attempted to delete without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var audiobook = this.db.audiobooks.find(a => a.id === req.params.id)
|
||||
if (!audiobook) return res.sendStatus(404)
|
||||
|
||||
|
|
@ -138,6 +146,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async batchDeleteAudiobooks(req, res) {
|
||||
if (!req.user.canDelete) {
|
||||
Logger.warn('User attempted to delete without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var { audiobookIds } = req.body
|
||||
if (!audiobookIds || !audiobookIds.length) {
|
||||
return res.sendStatus(500)
|
||||
|
|
@ -155,6 +167,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async batchUpdateAudiobooks(req, res) {
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.warn('User attempted to batch update without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var audiobooks = req.body
|
||||
if (!audiobooks || !audiobooks.length) {
|
||||
return res.sendStatus(500)
|
||||
|
|
@ -185,6 +201,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async updateAudiobookTracks(req, res) {
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.warn('User attempted to update audiotracks without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var audiobook = this.db.audiobooks.find(a => a.id === req.params.id)
|
||||
if (!audiobook) return res.sendStatus(404)
|
||||
var orderedFileData = req.body.orderedFileData
|
||||
|
|
@ -196,6 +216,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async updateAudiobook(req, res) {
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.warn('User attempted to update without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var audiobook = this.db.audiobooks.find(a => a.id === req.params.id)
|
||||
if (!audiobook) return res.sendStatus(404)
|
||||
var hasUpdates = audiobook.update(req.body)
|
||||
|
|
@ -276,6 +300,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async createUser(req, res) {
|
||||
if (!req.user.isRoot) {
|
||||
Logger.warn('Non-root user attempted to create user', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var account = req.body
|
||||
account.id = (Math.trunc(Math.random() * 1000) + Date.now()).toString(36)
|
||||
account.pash = await this.auth.hashPass(account.password)
|
||||
|
|
@ -297,7 +325,7 @@ class ApiController {
|
|||
}
|
||||
|
||||
async updateUser(req, res) {
|
||||
if (req.user.type !== 'root') {
|
||||
if (!req.user.isRoot) {
|
||||
Logger.error('User other than root attempting to update user', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
|
@ -327,6 +355,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async deleteUser(req, res) {
|
||||
if (!req.user.isRoot) {
|
||||
Logger.error('User other than root attempting to delete user', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
if (req.params.id === 'root') {
|
||||
return res.sendStatus(500)
|
||||
}
|
||||
|
|
@ -353,6 +385,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async updateServerSettings(req, res) {
|
||||
if (!req.user.isRoot) {
|
||||
Logger.error('User other than root attempting to update server settings', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var settingsUpdate = req.body
|
||||
if (!settingsUpdate || !isObject(settingsUpdate)) {
|
||||
return res.sendStatus(500)
|
||||
|
|
@ -368,6 +404,10 @@ class ApiController {
|
|||
}
|
||||
|
||||
async download(req, res) {
|
||||
if (!req.user.canDownload) {
|
||||
Logger.error('User attempting to download without permission', req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
var downloadId = req.params.id
|
||||
Logger.info('Download Request', downloadId)
|
||||
var download = this.downloadManager.getDownload(downloadId)
|
||||
|
|
|
|||
|
|
@ -75,11 +75,11 @@ class Db {
|
|||
async load() {
|
||||
var p1 = this.audiobooksDb.select(() => true).then((results) => {
|
||||
this.audiobooks = results.data.map(a => new Audiobook(a))
|
||||
Logger.info(`Audiobooks Loaded ${this.audiobooks.length}`)
|
||||
Logger.info(`[DB] Audiobooks Loaded ${this.audiobooks.length}`)
|
||||
})
|
||||
var p2 = this.usersDb.select(() => true).then((results) => {
|
||||
this.users = results.data.map(u => new User(u))
|
||||
Logger.info(`Users Loaded ${this.users.length}`)
|
||||
Logger.info(`[DB] Users Loaded ${this.users.length}`)
|
||||
})
|
||||
var p3 = this.settingsDb.select(() => true).then((results) => {
|
||||
if (results.data && results.data.length) {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,28 @@ class User {
|
|||
this.isActive = true
|
||||
this.createdAt = null
|
||||
this.audiobooks = null
|
||||
|
||||
this.settings = {}
|
||||
this.permissions = {}
|
||||
|
||||
if (user) {
|
||||
this.construct(user)
|
||||
}
|
||||
}
|
||||
|
||||
get isRoot() {
|
||||
return this.type === 'root'
|
||||
}
|
||||
get canDelete() {
|
||||
return !!this.permissions.delete
|
||||
}
|
||||
get canUpdate() {
|
||||
return !!this.permissions.update
|
||||
}
|
||||
get canDownload() {
|
||||
return !!this.permissions.download
|
||||
}
|
||||
|
||||
getDefaultUserSettings() {
|
||||
return {
|
||||
orderBy: 'book.title',
|
||||
|
|
@ -28,6 +43,14 @@ class User {
|
|||
}
|
||||
}
|
||||
|
||||
getDefaultUserPermissions() {
|
||||
return {
|
||||
download: true,
|
||||
update: true,
|
||||
delete: this.id === 'root'
|
||||
}
|
||||
}
|
||||
|
||||
audiobooksToJSON() {
|
||||
if (!this.audiobooks) return null
|
||||
var _map = {}
|
||||
|
|
@ -50,7 +73,8 @@ class User {
|
|||
audiobooks: this.audiobooksToJSON(),
|
||||
isActive: this.isActive,
|
||||
createdAt: this.createdAt,
|
||||
settings: this.settings
|
||||
settings: this.settings,
|
||||
permissions: this.permissions
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +88,8 @@ class User {
|
|||
audiobooks: this.audiobooksToJSON(),
|
||||
isActive: this.isActive,
|
||||
createdAt: this.createdAt,
|
||||
settings: this.settings
|
||||
settings: this.settings,
|
||||
permissions: this.permissions
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,10 +111,12 @@ class User {
|
|||
this.isActive = (user.isActive === undefined || user.id === 'root') ? true : !!user.isActive
|
||||
this.createdAt = user.createdAt || Date.now()
|
||||
this.settings = user.settings || this.getDefaultUserSettings()
|
||||
this.permissions = user.permissions || this.getDefaultUserPermissions()
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var hasUpdates = false
|
||||
// Update the following keys:
|
||||
const keysToCheck = ['pash', 'type', 'username', 'isActive']
|
||||
keysToCheck.forEach((key) => {
|
||||
if (payload[key] !== undefined) {
|
||||
|
|
@ -101,6 +128,15 @@ class User {
|
|||
}
|
||||
}
|
||||
})
|
||||
// And update permissions
|
||||
if (payload.permissions) {
|
||||
for (const key in payload.permissions) {
|
||||
if (payload.permissions[key] !== this.permissions[key]) {
|
||||
hasUpdates = true
|
||||
this.permissions[key] = payload.permissions[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue