diff --git a/.devcontainer/dev.js b/.devcontainer/dev.js index 054690d4f..1e5177e2d 100644 --- a/.devcontainer/dev.js +++ b/.devcontainer/dev.js @@ -6,5 +6,8 @@ module.exports.config = { MetadataPath: Path.resolve('metadata'), FFmpegPath: '/usr/bin/ffmpeg', FFProbePath: '/usr/bin/ffprobe', - SkipBinariesCheck: false + SkipBinariesCheck: false, + // Auto-create root user during initial setup + // InitUserName: 'admin', + // InitUserPassword: 'password' } diff --git a/index.js b/index.js index 7379322e8..200156784 100644 --- a/index.js +++ b/index.js @@ -31,6 +31,8 @@ if (isDev || options['prod-with-dev-env']) { if (devEnv.AllowIframe) process.env.ALLOW_IFRAME = '1' if (devEnv.BackupPath) process.env.BACKUP_PATH = devEnv.BackupPath if (devEnv.ReactClientPath) process.env.REACT_CLIENT_PATH = devEnv.ReactClientPath + if (devEnv.InitUserName) process.env.INIT_USER_NAME = devEnv.InitUserName + if (devEnv.InitUserPassword) process.env.INIT_USER_PASSWORD = devEnv.InitUserPassword process.env.SOURCE = 'local' process.env.ROUTER_BASE_PATH = devEnv.RouterBasePath ?? '/audiobookshelf' } diff --git a/server/Server.js b/server/Server.js index d6f748a1e..65e9cbd73 100644 --- a/server/Server.js +++ b/server/Server.js @@ -160,6 +160,9 @@ class Server { // Create or set JWT secret in token manager await this.auth.tokenManager.initTokenSecret() + // Auto-create root user if environment variables are set and no root user exists + await this.autoCreateRootUser() + await Logger.logManager.init() await this.cleanUserData() // Remove invalid user item progress @@ -428,6 +431,30 @@ class Server { SocketAuthority.initialize(this) } + async autoCreateRootUser() { + if (!Database.hasRootUser && process.env.INIT_USER_NAME) { + const initUsername = process.env.INIT_USER_NAME + const initPassword = process.env.INIT_USER_PASSWORD || '' + + Logger.info(`[Server] Auto-creating root user "${initUsername}" from environment variables`) + + try { + const hashedPassword = initPassword ? await this.auth.localAuthStrategy.hashPassword(initPassword) : '' + + if (!hashedPassword && initPassword) { + Logger.warn(`[Server] Failed to hash password for auto-created root user`) + } else if (!initPassword) { + Logger.warn(`[Server] Creating root user with no password`) + } + + await Database.createRootUser(initUsername, hashedPassword, this.auth) + Logger.info(`[Server] Successfully auto-created root user "${initUsername}"`) + } catch (error) { + Logger.error(`[Server] Failed to auto-create root user:`, error) + } + } + } + async initializeServer(req, res) { Logger.info(`[Server] Initializing new server`) const newRoot = req.body.newRoot