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:
advplyr 2022-05-14 17:23:22 -05:00
parent 63a8e2433e
commit c962090c3a
20 changed files with 287 additions and 149 deletions

View file

@ -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')

View file

@ -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()

View file

@ -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(),

View file

@ -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

View file

@ -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']