diff --git a/Dockerfile b/Dockerfile index fe2e0059..4a8e87aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,10 @@ RUN apk update && \ apk add --no-cache --update \ curl \ tzdata \ - ffmpeg + ffmpeg \ + make \ + python3 \ + g++ COPY --from=tone /usr/local/bin/tone /usr/local/bin/ COPY --from=build /client/dist /client/dist @@ -23,6 +26,8 @@ COPY server server RUN npm ci --only=production +RUN apk del make python3 g++ + EXPOSE 80 HEALTHCHECK \ --interval=30s \ diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index b323c820..8b86dad0 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -756,6 +756,8 @@ export default { this.store.commit('globals/setConfirmPrompt', payload) }, removeSeriesFromContinueListening() { + if (!this.series) return + const axios = this.$axios || this.$nuxt.$axios this.processing = true axios diff --git a/server/Database.js b/server/Database.js index e5e06fee..56632a6b 100644 --- a/server/Database.js +++ b/server/Database.js @@ -236,7 +236,7 @@ class Database { if (newCollection) { const collectionBooks = [] oldCollection.books.forEach((libraryItemId) => { - const libraryItem = this.libraryItems.filter(li => li.id === libraryItemId) + const libraryItem = this.libraryItems.find(li => li.id === libraryItemId) if (libraryItem) { collectionBooks.push({ collectionId: newCollection.id, diff --git a/server/Server.js b/server/Server.js index 3afd03d9..3d80e773 100644 --- a/server/Server.js +++ b/server/Server.js @@ -230,10 +230,10 @@ 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) : '' + const rootUsername = newRoot.username || 'root' + const 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', username: newRoot.username }) - await Database.createRootUser(newRoot.username, rootPash, rootToken) + await Database.createRootUser(rootUsername, rootPash, this.auth) res.sendStatus(200) } diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index 8bc38db7..5b2819b4 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -43,7 +43,8 @@ class LibraryController { } const library = new Library() - newLibraryPayload.displayOrder = Database.libraries.length + 1 + + newLibraryPayload.displayOrder = Database.libraries.map(li => li.displayOrder).sort((a, b) => a - b).pop() + 1 library.setData(newLibraryPayload) await Database.createLibrary(library) diff --git a/server/controllers/MiscController.js b/server/controllers/MiscController.js index cd7f12d5..0ed7ef8f 100644 --- a/server/controllers/MiscController.js +++ b/server/controllers/MiscController.js @@ -112,19 +112,19 @@ class MiscController { Logger.error('User other than admin attempting to update server settings', req.user) return res.sendStatus(403) } - var settingsUpdate = req.body + const settingsUpdate = req.body if (!settingsUpdate || !isObject(settingsUpdate)) { return res.status(500).send('Invalid settings update object') } - var madeUpdates = Database.serverSettings.update(settingsUpdate) + const madeUpdates = Database.serverSettings.update(settingsUpdate) if (madeUpdates) { + await Database.updateServerSettings() + // If backup schedule is updated - update backup manager if (settingsUpdate.backupSchedule !== undefined) { this.backupManager.updateCronSchedule() } - - await Database.updateServerSettings() } return res.json({ success: true, diff --git a/server/managers/EmailManager.js b/server/managers/EmailManager.js index 14106d72..1298b5b5 100644 --- a/server/managers/EmailManager.js +++ b/server/managers/EmailManager.js @@ -1,4 +1,5 @@ const nodemailer = require('nodemailer') +const Database = require('../Database') const Logger = require("../Logger") class EmailManager { diff --git a/server/managers/PlaybackSessionManager.js b/server/managers/PlaybackSessionManager.js index 0794d508..05151672 100644 --- a/server/managers/PlaybackSessionManager.js +++ b/server/managers/PlaybackSessionManager.js @@ -52,6 +52,7 @@ class PlaybackSessionManager { } } + await Database.createDevice(deviceInfo) return deviceInfo } @@ -221,9 +222,6 @@ class PlaybackSessionManager { newPlaybackSession.audioTracks = audioTracks } - // Will save on the first sync - user.currentSessionId = newPlaybackSession.id - this.sessions.push(newPlaybackSession) SocketAuthority.adminEmitter('user_stream_update', user.toJSONForPublic(this.sessions, Database.libraryItems)) diff --git a/server/models/Author.js b/server/models/Author.js index b100bbd8..8626e27c 100644 --- a/server/models/Author.js +++ b/server/models/Author.js @@ -77,7 +77,9 @@ module.exports = (sequelize) => { }) const { library } = sequelize.models - library.hasMany(Author) + library.hasMany(Author, { + onDelete: 'CASCADE' + }) Author.belongsTo(library) return Author diff --git a/server/models/CollectionBook.js b/server/models/CollectionBook.js index 0312e0be..16ab70c0 100644 --- a/server/models/CollectionBook.js +++ b/server/models/CollectionBook.js @@ -32,10 +32,14 @@ module.exports = (sequelize) => { book.belongsToMany(collection, { through: CollectionBook }) collection.belongsToMany(book, { through: CollectionBook }) - book.hasMany(CollectionBook) + book.hasMany(CollectionBook, { + onDelete: 'CASCADE' + }) CollectionBook.belongsTo(book) - collection.hasMany(CollectionBook) + collection.hasMany(CollectionBook, { + onDelete: 'CASCADE' + }) CollectionBook.belongsTo(collection) return CollectionBook diff --git a/server/models/Device.js b/server/models/Device.js index cde4ce7f..a8917c19 100644 --- a/server/models/Device.js +++ b/server/models/Device.js @@ -32,7 +32,9 @@ module.exports = (sequelize) => { static async getOldDeviceByDeviceId(deviceId) { const device = await this.findOne({ - deviceId + where: { + deviceId + } }) if (!device) return null return device.getOldDevice() @@ -105,7 +107,9 @@ module.exports = (sequelize) => { const { user } = sequelize.models - user.hasMany(Device) + user.hasMany(Device, { + onDelete: 'CASCADE' + }) Device.belongsTo(user) return Device diff --git a/server/models/FeedEpisode.js b/server/models/FeedEpisode.js index 405ab211..2525b664 100644 --- a/server/models/FeedEpisode.js +++ b/server/models/FeedEpisode.js @@ -73,7 +73,9 @@ module.exports = (sequelize) => { const { feed } = sequelize.models - feed.hasMany(FeedEpisode) + feed.hasMany(FeedEpisode, { + onDelete: 'CASCADE' + }) FeedEpisode.belongsTo(feed) return FeedEpisode diff --git a/server/models/Library.js b/server/models/Library.js index 6c8e8261..6fee9ad6 100644 --- a/server/models/Library.js +++ b/server/models/Library.js @@ -39,18 +39,19 @@ module.exports = (sequelize) => { * @param {object} oldLibrary * @returns {Library|null} */ - static createFromOld(oldLibrary) { + static async createFromOld(oldLibrary) { const library = this.getFromOld(oldLibrary) library.libraryFolders = oldLibrary.folders.map(folder => { return { id: folder.id, - path: folder.fullPath, - libraryId: library.id + path: folder.fullPath } }) - return this.create(library).catch((error) => { + return this.create(library, { + include: sequelize.models.libraryFolder + }).catch((error) => { Logger.error(`[Library] Failed to create library ${library.id}`, error) return null }) diff --git a/server/models/LibraryFolder.js b/server/models/LibraryFolder.js index 537947f3..6578dcde 100644 --- a/server/models/LibraryFolder.js +++ b/server/models/LibraryFolder.js @@ -16,7 +16,9 @@ module.exports = (sequelize) => { }) const { library } = sequelize.models - library.hasMany(LibraryFolder) + library.hasMany(LibraryFolder, { + onDelete: 'CASCADE' + }) LibraryFolder.belongsTo(library) return LibraryFolder diff --git a/server/models/MediaProgress.js b/server/models/MediaProgress.js index 913f46ec..d21085d2 100644 --- a/server/models/MediaProgress.js +++ b/server/models/MediaProgress.js @@ -134,7 +134,9 @@ module.exports = (sequelize) => { } }) - user.hasMany(MediaProgress) + user.hasMany(MediaProgress, { + onDelete: 'CASCADE' + }) MediaProgress.belongsTo(user) return MediaProgress diff --git a/server/models/PlaylistMediaItem.js b/server/models/PlaylistMediaItem.js index 7d2960e8..915739e6 100644 --- a/server/models/PlaylistMediaItem.js +++ b/server/models/PlaylistMediaItem.js @@ -75,7 +75,9 @@ module.exports = (sequelize) => { } }) - playlist.hasMany(PlaylistMediaItem) + playlist.hasMany(PlaylistMediaItem, { + onDelete: 'CASCADE' + }) PlaylistMediaItem.belongsTo(playlist) return PlaylistMediaItem diff --git a/server/models/Series.js b/server/models/Series.js index 85519b98..b71f3e9d 100644 --- a/server/models/Series.js +++ b/server/models/Series.js @@ -71,7 +71,9 @@ module.exports = (sequelize) => { }) const { library } = sequelize.models - library.hasMany(Series) + library.hasMany(Series, { + onDelete: 'CASCADE' + }) Series.belongsTo(library) return Series diff --git a/server/models/User.js b/server/models/User.js index e7656310..32b2b436 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -89,9 +89,13 @@ module.exports = (sequelize) => { }) } - static async createRootUser(username, pash, token) { + static async createRootUser(username, pash, auth) { + const userId = uuidv4() + + const token = await auth.generateAccessToken({ userId, username }) + const newRoot = new oldUser({ - id: uuidv4(), + id: userId, type: 'root', username, pash, diff --git a/server/objects/DeviceInfo.js b/server/objects/DeviceInfo.js index 2f7438cc..ceff6c32 100644 --- a/server/objects/DeviceInfo.js +++ b/server/objects/DeviceInfo.js @@ -90,7 +90,7 @@ class DeviceInfo { setData(ip, ua, clientDeviceInfo, serverVersion, userId) { this.id = uuidv4() this.userId = userId - this.deviceId = clientDeviceInfo?.deviceId || null + this.deviceId = clientDeviceInfo?.deviceId || this.id this.ipAddress = ip || null this.browserName = ua?.browser.name || null diff --git a/server/utils/migrations/dbMigration.js b/server/utils/migrations/dbMigration.js index 676f2344..35877fb6 100644 --- a/server/utils/migrations/dbMigration.js +++ b/server/utils/migrations/dbMigration.js @@ -432,7 +432,11 @@ function migrateUsers(oldUsers) { function migrateSessions(oldSessions) { for (const oldSession of oldSessions) { - const userId = oldDbIdMap.users[oldSession.userId] || null // Can be null + const userId = oldDbIdMap.users[oldSession.userId] + if (!userId) { + Logger.debug(`[dbMigration] Not migrating playback session ${oldSession.id} because user was not found`) + continue + } // // Migrate Device