|
|
|
@ -7,6 +7,9 @@ const paths = require('./pathsController') |
|
|
|
|
const perms = require('./permissionController') |
|
|
|
|
const uploadController = require('./uploadController') |
|
|
|
|
const utils = require('./utilsController') |
|
|
|
|
const apiErrorsHandler = require('./handlers/apiErrorsHandler.js') |
|
|
|
|
const ClientError = require('./utils/ClientError') |
|
|
|
|
const ServerError = require('./utils/ServerError') |
|
|
|
|
const config = require('./../config') |
|
|
|
|
const logger = require('./../logger') |
|
|
|
|
const db = require('knex')(config.database) |
|
|
|
@ -66,28 +69,27 @@ self.getUniqueRandomName = async () => { |
|
|
|
|
return identifier |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
throw 'Sorry, we could not allocate a unique random identifier. Try again?' |
|
|
|
|
throw new ServerError('Failed to allocate a unique identifier for the album. Try again?') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.list = async (req, res, next) => { |
|
|
|
|
const user = await utils.authorize(req, res) |
|
|
|
|
if (!user) return |
|
|
|
|
try { |
|
|
|
|
const user = await utils.authorize(req) |
|
|
|
|
|
|
|
|
|
const all = req.headers.all === '1' |
|
|
|
|
const simple = req.headers.simple |
|
|
|
|
const ismoderator = perms.is(user, 'moderator') |
|
|
|
|
if (all && !ismoderator) return res.status(403).end() |
|
|
|
|
const all = req.headers.all === '1' |
|
|
|
|
const simple = req.headers.simple |
|
|
|
|
const ismoderator = perms.is(user, 'moderator') |
|
|
|
|
if (all && !ismoderator) return res.status(403).end() |
|
|
|
|
|
|
|
|
|
const filter = function () { |
|
|
|
|
if (!all) { |
|
|
|
|
this.where({ |
|
|
|
|
enabled: 1, |
|
|
|
|
userid: user.id |
|
|
|
|
}) |
|
|
|
|
const filter = function () { |
|
|
|
|
if (!all) { |
|
|
|
|
this.where({ |
|
|
|
|
enabled: 1, |
|
|
|
|
userid: user.id |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
// Query albums count for pagination
|
|
|
|
|
const count = await db.table('albums') |
|
|
|
|
.where(filter) |
|
|
|
@ -162,24 +164,22 @@ self.list = async (req, res, next) => { |
|
|
|
|
users[user.id] = user.username |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return res.json({ success: true, albums, count, users, homeDomain }) |
|
|
|
|
await res.json({ success: true, albums, count, users, homeDomain }) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.create = async (req, res, next) => { |
|
|
|
|
const user = await utils.authorize(req, res) |
|
|
|
|
if (!user) return |
|
|
|
|
try { |
|
|
|
|
const user = await utils.authorize(req) |
|
|
|
|
|
|
|
|
|
const name = typeof req.body.name === 'string' |
|
|
|
|
? utils.escape(req.body.name.trim().substring(0, self.titleMaxLength)) |
|
|
|
|
: '' |
|
|
|
|
const name = typeof req.body.name === 'string' |
|
|
|
|
? utils.escape(req.body.name.trim().substring(0, self.titleMaxLength)) |
|
|
|
|
: '' |
|
|
|
|
|
|
|
|
|
if (!name) return res.json({ success: false, description: 'No album name specified.' }) |
|
|
|
|
if (!name) throw new ClientError('No album name specified.') |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const album = await db.table('albums') |
|
|
|
|
.where({ |
|
|
|
|
name, |
|
|
|
@ -188,7 +188,7 @@ self.create = async (req, res, next) => { |
|
|
|
|
}) |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if (album) return res.json({ success: false, description: 'There is already an album with that name.' }) |
|
|
|
|
if (album) throw new ClientError('Album name already in use.', { statusCode: 403 }) |
|
|
|
|
|
|
|
|
|
const identifier = await self.getUniqueRandomName() |
|
|
|
|
|
|
|
|
@ -209,10 +209,9 @@ self.create = async (req, res, next) => { |
|
|
|
|
utils.invalidateStatsCache('albums') |
|
|
|
|
self.onHold.delete(identifier) |
|
|
|
|
|
|
|
|
|
return res.json({ success: true, id: ids[0] }) |
|
|
|
|
await res.json({ success: true, id: ids[0] }) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -222,14 +221,13 @@ self.delete = async (req, res, next) => { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.disable = async (req, res, next) => { |
|
|
|
|
const user = await utils.authorize(req, res) |
|
|
|
|
if (!user) return |
|
|
|
|
try { |
|
|
|
|
const user = await utils.authorize(req) |
|
|
|
|
|
|
|
|
|
const id = req.body.id |
|
|
|
|
const purge = req.body.purge |
|
|
|
|
if (!Number.isFinite(id)) return res.json({ success: false, description: 'No album specified.' }) |
|
|
|
|
const id = req.body.id |
|
|
|
|
const purge = req.body.purge |
|
|
|
|
if (!Number.isFinite(id)) throw new ClientError('No album specified.') |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
if (purge) { |
|
|
|
|
const files = await db.table('files') |
|
|
|
|
.where({ |
|
|
|
@ -263,55 +261,72 @@ self.disable = async (req, res, next) => { |
|
|
|
|
.first() |
|
|
|
|
.then(row => row.identifier) |
|
|
|
|
|
|
|
|
|
await paths.unlink(path.join(paths.zips, `${identifier}.zip`)) |
|
|
|
|
} catch (error) { |
|
|
|
|
if (error && error.code !== 'ENOENT') { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
try { |
|
|
|
|
await paths.unlink(path.join(paths.zips, `${identifier}.zip`)) |
|
|
|
|
} catch (error) { |
|
|
|
|
// Re-throw non-ENOENT error
|
|
|
|
|
if (error.code !== 'ENOENT') throw error |
|
|
|
|
} |
|
|
|
|
await res.json({ success: true }) |
|
|
|
|
} catch (error) { |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return res.json({ success: true }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.edit = async (req, res, next) => { |
|
|
|
|
const user = await utils.authorize(req, res) |
|
|
|
|
if (!user) return |
|
|
|
|
try { |
|
|
|
|
const user = await utils.authorize(req) |
|
|
|
|
|
|
|
|
|
const ismoderator = perms.is(user, 'moderator') |
|
|
|
|
const ismoderator = perms.is(user, 'moderator') |
|
|
|
|
|
|
|
|
|
const id = parseInt(req.body.id) |
|
|
|
|
if (isNaN(id)) return res.json({ success: false, description: 'No album specified.' }) |
|
|
|
|
const id = parseInt(req.body.id) |
|
|
|
|
if (isNaN(id)) throw new ClientError('No album specified.') |
|
|
|
|
|
|
|
|
|
const name = typeof req.body.name === 'string' |
|
|
|
|
? utils.escape(req.body.name.trim().substring(0, self.titleMaxLength)) |
|
|
|
|
: '' |
|
|
|
|
const name = typeof req.body.name === 'string' |
|
|
|
|
? utils.escape(req.body.name.trim().substring(0, self.titleMaxLength)) |
|
|
|
|
: '' |
|
|
|
|
|
|
|
|
|
if (!name) return res.json({ success: false, description: 'No name specified.' }) |
|
|
|
|
if (!name) throw new ClientError('No album name specified.') |
|
|
|
|
|
|
|
|
|
const filter = function () { |
|
|
|
|
this.where('id', id) |
|
|
|
|
const filter = function () { |
|
|
|
|
this.where('id', id) |
|
|
|
|
|
|
|
|
|
if (!ismoderator) { |
|
|
|
|
this.andWhere({ |
|
|
|
|
enabled: 1, |
|
|
|
|
userid: user.id |
|
|
|
|
}) |
|
|
|
|
if (!ismoderator) { |
|
|
|
|
this.andWhere({ |
|
|
|
|
enabled: 1, |
|
|
|
|
userid: user.id |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const album = await db.table('albums') |
|
|
|
|
.where(filter) |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if (!album) { |
|
|
|
|
return res.json({ success: false, description: 'Could not get album with the specified ID.' }) |
|
|
|
|
} else if (album.id !== id) { |
|
|
|
|
return res.json({ success: false, description: 'Name already in use.' }) |
|
|
|
|
} else if (req._old && (album.id === id)) { |
|
|
|
|
// Old rename API
|
|
|
|
|
return res.json({ success: false, description: 'You did not specify a new name.' }) |
|
|
|
|
throw new ClientError('Could not get album with the specified ID.') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const albumNewState = (ismoderator && typeof req.body.enabled !== 'undefined') |
|
|
|
|
? Boolean(req.body.enabled) |
|
|
|
|
: null |
|
|
|
|
|
|
|
|
|
const nameInUse = await db.table('albums') |
|
|
|
|
.where({ |
|
|
|
|
name, |
|
|
|
|
enabled: 1, |
|
|
|
|
userid: user.id |
|
|
|
|
}) |
|
|
|
|
.whereNot('id', id) |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if ((album.enabled || (albumNewState === true)) && nameInUse) { |
|
|
|
|
if (req._old) { |
|
|
|
|
// Old rename API (stick with 200 status code for this)
|
|
|
|
|
throw new ClientError('You did not specify a new name.', { statusCode: 200 }) |
|
|
|
|
} else { |
|
|
|
|
throw new ClientError('Album name already in use.', { statusCode: 403 }) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const update = { |
|
|
|
@ -323,8 +338,8 @@ self.edit = async (req, res, next) => { |
|
|
|
|
: '' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ismoderator && typeof req.body.enabled !== 'undefined') { |
|
|
|
|
update.enabled = Boolean(req.body.enabled) |
|
|
|
|
if (albumNewState !== null) { |
|
|
|
|
update.enabled = albumNewState |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (req.body.requestLink) { |
|
|
|
@ -346,20 +361,19 @@ self.edit = async (req, res, next) => { |
|
|
|
|
const newZip = path.join(paths.zips, `${update.identifier}.zip`) |
|
|
|
|
await paths.rename(oldZip, newZip) |
|
|
|
|
} catch (error) { |
|
|
|
|
// Re-throw error
|
|
|
|
|
// Re-throw non-ENOENT error
|
|
|
|
|
if (error.code !== 'ENOENT') throw error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return res.json({ |
|
|
|
|
await res.json({ |
|
|
|
|
success: true, |
|
|
|
|
identifier: update.identifier |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
return res.json({ success: true, name }) |
|
|
|
|
await res.json({ success: true, name }) |
|
|
|
|
} |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -370,12 +384,12 @@ self.rename = async (req, res, next) => { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.get = async (req, res, next) => { |
|
|
|
|
const identifier = req.params.identifier |
|
|
|
|
if (identifier === undefined) { |
|
|
|
|
return res.status(401).json({ success: false, description: 'No identifier provided.' }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const identifier = req.params.identifier |
|
|
|
|
if (identifier === undefined) { |
|
|
|
|
throw new ClientError('No identifier provided.') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const album = await db.table('albums') |
|
|
|
|
.where({ |
|
|
|
|
identifier, |
|
|
|
@ -384,7 +398,7 @@ self.get = async (req, res, next) => { |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if (!album || album.public === 0) { |
|
|
|
|
return res.status(404).json({ success: false, description: 'The album could not be found.' }) |
|
|
|
|
throw new ClientError('Album not found.', { statusCode: 404 }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const title = album.name |
|
|
|
@ -407,7 +421,7 @@ self.get = async (req, res, next) => { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return res.json({ |
|
|
|
|
await res.json({ |
|
|
|
|
success: true, |
|
|
|
|
description: 'Successfully retrieved files.', |
|
|
|
|
title, |
|
|
|
@ -416,30 +430,23 @@ self.get = async (req, res, next) => { |
|
|
|
|
files |
|
|
|
|
}) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occcured. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.generateZip = async (req, res, next) => { |
|
|
|
|
const versionString = parseInt(req.query.v) |
|
|
|
|
try { |
|
|
|
|
const versionString = parseInt(req.query.v) |
|
|
|
|
|
|
|
|
|
const identifier = req.params.identifier |
|
|
|
|
if (identifier === undefined) { |
|
|
|
|
return res.status(401).json({ |
|
|
|
|
success: false, |
|
|
|
|
description: 'No identifier provided.' |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
const identifier = req.params.identifier |
|
|
|
|
if (identifier === undefined) { |
|
|
|
|
throw new ClientError('No identifier provided.') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!config.uploads.generateZips) { |
|
|
|
|
return res.status(401).json({ |
|
|
|
|
success: false, |
|
|
|
|
description: 'ZIP generation disabled.' |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
if (!config.uploads.generateZips) { |
|
|
|
|
throw new ClientError('ZIP generation disabled.', { statusCode: 403 }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const album = await db.table('albums') |
|
|
|
|
.where({ |
|
|
|
|
identifier, |
|
|
|
@ -448,9 +455,9 @@ self.generateZip = async (req, res, next) => { |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if (!album) { |
|
|
|
|
return res.json({ success: false, description: 'Album not found.' }) |
|
|
|
|
throw new ClientError('Album not found.', { statusCode: 404 }) |
|
|
|
|
} else if (album.download === 0) { |
|
|
|
|
return res.json({ success: false, description: 'Download for this album is disabled.' }) |
|
|
|
|
throw new ClientError('Download for this album is disabled.', { statusCode: 403 }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((isNaN(versionString) || versionString <= 0) && album.editedAt) { |
|
|
|
@ -461,20 +468,20 @@ self.generateZip = async (req, res, next) => { |
|
|
|
|
try { |
|
|
|
|
const filePath = path.join(paths.zips, `${identifier}.zip`) |
|
|
|
|
await paths.access(filePath) |
|
|
|
|
return res.download(filePath, `${album.name}.zip`) |
|
|
|
|
await res.download(filePath, `${album.name}.zip`) |
|
|
|
|
} catch (error) { |
|
|
|
|
// Re-throw error
|
|
|
|
|
// Re-throw non-ENOENT error
|
|
|
|
|
if (error.code !== 'ENOENT') throw error |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (self.zipEmitters.has(identifier)) { |
|
|
|
|
logger.log(`Waiting previous zip task for album: ${identifier}.`) |
|
|
|
|
return self.zipEmitters.get(identifier).once('done', (filePath, fileName, json) => { |
|
|
|
|
return self.zipEmitters.get(identifier).once('done', (filePath, fileName, clientErr) => { |
|
|
|
|
if (filePath && fileName) { |
|
|
|
|
res.download(filePath, fileName) |
|
|
|
|
} else if (json) { |
|
|
|
|
res.json(json) |
|
|
|
|
} else if (clientErr) { |
|
|
|
|
apiErrorsHandler(clientErr, req, res, next) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
@ -488,24 +495,18 @@ self.generateZip = async (req, res, next) => { |
|
|
|
|
.where('albumid', album.id) |
|
|
|
|
if (files.length === 0) { |
|
|
|
|
logger.log(`Finished zip task for album: ${identifier} (no files).`) |
|
|
|
|
const json = { |
|
|
|
|
success: false, |
|
|
|
|
description: 'There are no files in the album.' |
|
|
|
|
} |
|
|
|
|
self.zipEmitters.get(identifier).emit('done', null, null, json) |
|
|
|
|
return res.json(json) |
|
|
|
|
const clientErr = new ClientError('There are no files in the album.', { statusCode: 200 }) |
|
|
|
|
self.zipEmitters.get(identifier).emit('done', null, null, clientErr) |
|
|
|
|
throw clientErr |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (zipMaxTotalSize) { |
|
|
|
|
const totalSizeBytes = files.reduce((accumulator, file) => accumulator + parseInt(file.size), 0) |
|
|
|
|
if (totalSizeBytes > zipMaxTotalSizeBytes) { |
|
|
|
|
logger.log(`Finished zip task for album: ${identifier} (size exceeds).`) |
|
|
|
|
const json = { |
|
|
|
|
success: false, |
|
|
|
|
description: `Total size of all files in the album exceeds the configured limit (${zipMaxTotalSize} MB).` |
|
|
|
|
} |
|
|
|
|
self.zipEmitters.get(identifier).emit('done', null, null, json) |
|
|
|
|
return res.json(json) |
|
|
|
|
const clientErr = new ClientError(`Total size of all files in the album exceeds ${zipMaxTotalSize} MB limit.`, { statusCode: 403 }) |
|
|
|
|
self.zipEmitters.get(identifier).emit('done', null, null, clientErr) |
|
|
|
|
throw clientErr |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -528,10 +529,7 @@ self.generateZip = async (req, res, next) => { |
|
|
|
|
}) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ |
|
|
|
|
success: 'false', |
|
|
|
|
description: error.toString() |
|
|
|
|
}) |
|
|
|
|
throw new ServerError(error.message) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
logger.log(`Finished zip task for album: ${identifier} (success).`) |
|
|
|
@ -545,10 +543,9 @@ self.generateZip = async (req, res, next) => { |
|
|
|
|
const fileName = `${album.name}.zip` |
|
|
|
|
|
|
|
|
|
self.zipEmitters.get(identifier).emit('done', filePath, fileName) |
|
|
|
|
return res.download(filePath, fileName) |
|
|
|
|
await res.download(filePath, fileName) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -589,20 +586,20 @@ self.listFiles = async (req, res, next) => { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.addFiles = async (req, res, next) => { |
|
|
|
|
const user = await utils.authorize(req, res) |
|
|
|
|
if (!user) return |
|
|
|
|
let ids, albumid, failed, albumids |
|
|
|
|
try { |
|
|
|
|
const user = await utils.authorize(req) |
|
|
|
|
|
|
|
|
|
const ids = req.body.ids |
|
|
|
|
if (!Array.isArray(ids) || !ids.length) { |
|
|
|
|
return res.json({ success: false, description: 'No files specified.' }) |
|
|
|
|
} |
|
|
|
|
ids = req.body.ids |
|
|
|
|
if (!Array.isArray(ids) || !ids.length) { |
|
|
|
|
throw new ClientError('No files specified.') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let albumid = parseInt(req.body.albumid) |
|
|
|
|
if (isNaN(albumid) || albumid < 0) albumid = null |
|
|
|
|
albumid = parseInt(req.body.albumid) |
|
|
|
|
if (isNaN(albumid) || albumid < 0) albumid = null |
|
|
|
|
|
|
|
|
|
let failed = [] |
|
|
|
|
const albumids = [] |
|
|
|
|
try { |
|
|
|
|
failed = [] |
|
|
|
|
albumids = [] |
|
|
|
|
if (albumid !== null) { |
|
|
|
|
const album = await db.table('albums') |
|
|
|
|
.where('id', albumid) |
|
|
|
@ -614,10 +611,7 @@ self.addFiles = async (req, res, next) => { |
|
|
|
|
.first() |
|
|
|
|
|
|
|
|
|
if (!album) { |
|
|
|
|
return res.json({ |
|
|
|
|
success: false, |
|
|
|
|
description: 'Album does not exist or it does not belong to the user.' |
|
|
|
|
}) |
|
|
|
|
throw new ClientError('Album does not exist or it does not belong to the user.', { statusCode: 404 }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
albumids.push(albumid) |
|
|
|
@ -632,6 +626,7 @@ self.addFiles = async (req, res, next) => { |
|
|
|
|
await db.table('files') |
|
|
|
|
.whereIn('id', files.map(file => file.id)) |
|
|
|
|
.update('albumid', albumid) |
|
|
|
|
utils.invalidateStatsCache('albums') |
|
|
|
|
|
|
|
|
|
files.forEach(file => { |
|
|
|
|
if (file.albumid && !albumids.includes(file.albumid)) { |
|
|
|
@ -644,16 +639,12 @@ self.addFiles = async (req, res, next) => { |
|
|
|
|
.update('editedAt', Math.floor(Date.now() / 1000)) |
|
|
|
|
utils.invalidateAlbumsCache(albumids) |
|
|
|
|
|
|
|
|
|
return res.json({ success: true, failed }) |
|
|
|
|
await res.json({ success: true, failed }) |
|
|
|
|
} catch (error) { |
|
|
|
|
logger.error(error) |
|
|
|
|
if (failed.length === ids.length) { |
|
|
|
|
return res.json({ |
|
|
|
|
success: false, |
|
|
|
|
description: `Could not ${albumid === null ? 'add' : 'remove'} any files ${albumid === null ? 'to' : 'from'} the album.` |
|
|
|
|
}) |
|
|
|
|
if (Array.isArray(failed) && (failed.length === ids.length)) { |
|
|
|
|
return apiErrorsHandler(new ServerError(`Could not ${albumid === null ? 'add' : 'remove'} any files ${albumid === null ? 'to' : 'from'} the album.`), req, res, next) |
|
|
|
|
} else { |
|
|
|
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' }) |
|
|
|
|
return apiErrorsHandler(error, req, res, next) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|