mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-24 04:39:40 +00:00
Update:No longer creating initial root user and initial library, add init root user page, web app works with no libraries
This commit is contained in:
parent
63a8e2433e
commit
c962090c3a
20 changed files with 287 additions and 149 deletions
|
|
@ -17,14 +17,6 @@ class Auth {
|
|||
return this.db.users
|
||||
}
|
||||
|
||||
init() {
|
||||
var root = this.users.find(u => u.type === 'root')
|
||||
if (!root) {
|
||||
Logger.fatal('No Root User', this.users)
|
||||
throw new Error('No Root User')
|
||||
}
|
||||
}
|
||||
|
||||
cors(req, res, next) {
|
||||
res.header('Access-Control-Allow-Origin', '*')
|
||||
res.header("Access-Control-Allow-Methods", 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
|
||||
|
|
|
|||
68
server/Db.js
68
server/Db.js
|
|
@ -46,6 +46,10 @@ class Db {
|
|||
this.previousVersion = null
|
||||
}
|
||||
|
||||
get hasRootUser() {
|
||||
return this.users.some(u => u.id === 'root')
|
||||
}
|
||||
|
||||
getEntityDb(entityName) {
|
||||
if (entityName === 'user') return this.usersDb
|
||||
else if (entityName === 'session') return this.sessionsDb
|
||||
|
|
@ -70,33 +74,6 @@ class Db {
|
|||
return null
|
||||
}
|
||||
|
||||
getDefaultUser(token) {
|
||||
return new User({
|
||||
id: 'root',
|
||||
type: 'root',
|
||||
username: 'root',
|
||||
pash: '',
|
||||
stream: null,
|
||||
token,
|
||||
isActive: true,
|
||||
createdAt: Date.now()
|
||||
})
|
||||
}
|
||||
|
||||
getDefaultLibrary() {
|
||||
var defaultLibrary = new Library()
|
||||
defaultLibrary.setData({
|
||||
id: 'main',
|
||||
name: 'Main',
|
||||
folder: { // Generates default folder
|
||||
id: 'audiobooks',
|
||||
fullPath: global.AudiobookPath,
|
||||
libraryId: 'main'
|
||||
}
|
||||
})
|
||||
return defaultLibrary
|
||||
}
|
||||
|
||||
reinit() {
|
||||
this.libraryItemsDb = new njodb.Database(this.LibraryItemsPath)
|
||||
this.usersDb = new njodb.Database(this.UsersPath)
|
||||
|
|
@ -123,23 +100,36 @@ class Db {
|
|||
})
|
||||
}
|
||||
|
||||
createRootUser(username, pash, token) {
|
||||
const newRoot = new User({
|
||||
id: 'root',
|
||||
type: 'root',
|
||||
username,
|
||||
pash,
|
||||
token,
|
||||
isActive: true,
|
||||
createdAt: Date.now()
|
||||
})
|
||||
return this.insertEntity('user', newRoot)
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.load()
|
||||
|
||||
// Insert Defaults
|
||||
var rootUser = this.users.find(u => u.type === 'root')
|
||||
if (!rootUser) {
|
||||
var token = await jwt.sign({ userId: 'root' }, process.env.TOKEN_SECRET)
|
||||
Logger.debug('Generated default token', token)
|
||||
Logger.info('[Db] Root user created')
|
||||
await this.insertEntity('user', this.getDefaultUser(token))
|
||||
} else {
|
||||
Logger.info(`[Db] Root user exists, pw: ${rootUser.hasPw}`)
|
||||
}
|
||||
// var rootUser = this.users.find(u => u.type === 'root')
|
||||
// if (!rootUser) {
|
||||
// var token = await jwt.sign({ userId: 'root' }, process.env.TOKEN_SECRET)
|
||||
// Logger.debug('Generated default token', token)
|
||||
// Logger.info('[Db] Root user created')
|
||||
// await this.insertEntity('user', this.getDefaultUser(token))
|
||||
// } else {
|
||||
// Logger.info(`[Db] Root user exists, pw: ${rootUser.hasPw}`)
|
||||
// }
|
||||
|
||||
if (!this.libraries.length) {
|
||||
await this.insertEntity('library', this.getDefaultLibrary())
|
||||
}
|
||||
// if (!this.libraries.length) {
|
||||
// await this.insertEntity('library', this.getDefaultLibrary())
|
||||
// }
|
||||
|
||||
if (!this.serverSettings) {
|
||||
this.serverSettings = new ServerSettings()
|
||||
|
|
|
|||
|
|
@ -34,18 +34,18 @@ const AudioMetadataMangaer = require('./managers/AudioMetadataManager')
|
|||
const RssFeedManager = require('./managers/RssFeedManager')
|
||||
|
||||
class Server {
|
||||
constructor(PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, AUDIOBOOK_PATH) {
|
||||
constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH) {
|
||||
this.Source = SOURCE
|
||||
this.Port = PORT
|
||||
this.Host = HOST
|
||||
global.Uid = isNaN(UID) ? 0 : Number(UID)
|
||||
global.Gid = isNaN(GID) ? 0 : Number(GID)
|
||||
global.ConfigPath = Path.normalize(CONFIG_PATH)
|
||||
global.AudiobookPath = Path.normalize(AUDIOBOOK_PATH)
|
||||
global.MetadataPath = Path.normalize(METADATA_PATH)
|
||||
|
||||
// Fix backslash if not on Windows
|
||||
if (process.platform !== 'win32') {
|
||||
global.ConfigPath = global.ConfigPath.replace(/\\/g, '/')
|
||||
global.AudiobookPath = global.AudiobookPath.replace(/\\/g, '/')
|
||||
global.MetadataPath = global.MetadataPath.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
|
|
@ -57,10 +57,6 @@ class Server {
|
|||
fs.mkdirSync(global.MetadataPath)
|
||||
filePerms.setDefaultDirSync(global.MetadataPath, false)
|
||||
}
|
||||
if (!fs.pathExistsSync(global.AudiobookPath)) {
|
||||
fs.mkdirSync(global.AudiobookPath)
|
||||
filePerms.setDefaultDirSync(global.AudiobookPath, false)
|
||||
}
|
||||
|
||||
this.db = new Db()
|
||||
this.watcher = new Watcher()
|
||||
|
|
@ -140,8 +136,6 @@ class Server {
|
|||
await this.db.init()
|
||||
}
|
||||
|
||||
this.auth.init()
|
||||
|
||||
await this.checkUserMediaProgress() // Remove invalid user item progress
|
||||
await this.purgeMetadata() // Remove metadata folders without library item
|
||||
|
||||
|
|
@ -231,6 +225,25 @@ class Server {
|
|||
|
||||
app.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res))
|
||||
app.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
|
||||
app.post('/init', (req, res) => {
|
||||
if (this.db.hasRootUser) {
|
||||
Logger.error(`[Server] attempt to init server when server already has a root user`)
|
||||
return res.sendStatus(500)
|
||||
}
|
||||
this.initializeServer(req, res)
|
||||
})
|
||||
app.get('/status', (req, res) => {
|
||||
// status check for client to see if server has been initialized
|
||||
// server has been initialized if a root user exists
|
||||
const payload = {
|
||||
isInit: this.db.hasRootUser
|
||||
}
|
||||
if (!payload.isInit) {
|
||||
payload.ConfigPath = global.ConfigPath
|
||||
payload.MetadataPath = global.MetadataPath
|
||||
}
|
||||
res.json(payload)
|
||||
})
|
||||
app.get('/ping', (req, res) => {
|
||||
Logger.info('Recieved ping')
|
||||
res.json({ success: true })
|
||||
|
|
@ -293,6 +306,17 @@ class Server {
|
|||
})
|
||||
}
|
||||
|
||||
async initializeServer(req, res) {
|
||||
Logger.info(`[Server] Initializing new server`)
|
||||
const newRoot = req.body.newRoot
|
||||
let rootPash = newRoot.password ? await this.auth.hashPass(newRoot.password) : ''
|
||||
if (!rootPash) Logger.warn(`[Server] Creating root user with no password`)
|
||||
let rootToken = await this.auth.generateAccessToken({ userId: 'root' })
|
||||
await this.db.createRootUser(newRoot.username, rootPash, rootToken)
|
||||
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
async filesChanged(fileUpdates) {
|
||||
Logger.info('[Server]', fileUpdates.length, 'Files Changed')
|
||||
await this.scanner.scanFilesChanged(fileUpdates)
|
||||
|
|
@ -433,7 +457,6 @@ class Server {
|
|||
const initialPayload = {
|
||||
// TODO: this is sent with user auth now, update mobile app to use that then remove this
|
||||
serverSettings: this.db.serverSettings.toJSON(),
|
||||
audiobookPath: global.AudiobookPath,
|
||||
metadataPath: global.MetadataPath,
|
||||
configPath: global.ConfigPath,
|
||||
user: client.user.toJSONForBrowser(),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class LibraryController {
|
|||
newLibraryPayload.displayOrder = this.db.libraries.length + 1
|
||||
library.setData(newLibraryPayload)
|
||||
await this.db.insertEntity('library', library)
|
||||
// TODO: Only emit to users that have access
|
||||
this.emitter('library_added', library.toJSON())
|
||||
|
||||
// Add library watcher
|
||||
|
|
|
|||
|
|
@ -242,13 +242,6 @@ class DownloadManager {
|
|||
if (shouldIncludeCover) {
|
||||
var _cover = audiobook.book.coverFullPath.replace(/\\/g, '/')
|
||||
|
||||
// Supporting old local file prefix
|
||||
var bookCoverPath = audiobook.book.cover ? audiobook.book.cover.replace(/\\/g, '/') : null
|
||||
if (!_cover && bookCoverPath && bookCoverPath.startsWith('/local')) {
|
||||
_cover = Path.posix.join(global.AudiobookPath, _cover.replace('/local', ''))
|
||||
Logger.debug('Local cover url', _cover)
|
||||
}
|
||||
|
||||
ffmpegInputs.push({
|
||||
input: _cover,
|
||||
options: ['-f image2pipe']
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue