diff --git a/public/src/modules/uploader.js b/public/src/modules/uploader.js index a9e91e7631..9ce81b97af 100644 --- a/public/src/modules/uploader.js +++ b/public/src/modules/uploader.js @@ -61,6 +61,7 @@ define('uploader', ['jquery-form'], function () { if (type === 'error') { uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); } + message = message.replace(/&#44/g, ','); uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); } @@ -72,7 +73,13 @@ define('uploader', ['jquery-form'], function () { }, error: function (xhr) { xhr = maybeParse(xhr); - showAlert(uploadModal, 'error', xhr.responseJSON?.status?.message || `[[error:upload-error-fallback, ${xhr.status} ${xhr.statusText}]]`); + showAlert( + uploadModal, + 'error', + xhr.responseJSON?.status?.message || // apiv3 + xhr.responseJSON?.error || // { "error": "[[error:some-error]]]" } + `[[error:upload-error-fallback, ${xhr.status} ${xhr.statusText}]]` + ); }, uploadProgress: function (event, position, total, percent) { uploadModal.find('#upload-progress-bar').css('width', percent + '%'); @@ -99,7 +106,7 @@ define('uploader', ['jquery-form'], function () { function maybeParse(response) { if (typeof response === 'string') { try { - return $.parseJSON(response); + return JSON.parse(response); } catch (e) { return { error: '[[error:parse-error]]' }; } diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index 6c20300e17..0f476c5c47 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -118,25 +118,23 @@ uploadsController.uploadCategoryPicture = async function (req, res, next) { return next(new Error('[[error:invalid-json]]')); } - if (validateUpload(res, uploadedFile, allowedImageTypes)) { - const filename = `category-${params.cid}${path.extname(uploadedFile.name)}`; - await uploadImage(filename, 'category', uploadedFile, req, res, next); - } + await validateUpload(uploadedFile, allowedImageTypes); + const filename = `category-${params.cid}${path.extname(uploadedFile.name)}`; + await uploadImage(filename, 'category', uploadedFile, req, res, next); }; uploadsController.uploadFavicon = async function (req, res, next) { const uploadedFile = req.files.files[0]; const allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon']; - if (validateUpload(res, uploadedFile, allowedTypes)) { - try { - const imageObj = await file.saveFileToLocal('favicon.ico', 'system', uploadedFile.path); - res.json([{ name: uploadedFile.name, url: imageObj.url }]); - } catch (err) { - next(err); - } finally { - file.delete(uploadedFile.path); - } + await validateUpload(uploadedFile, allowedTypes); + try { + const imageObj = await file.saveFileToLocal('favicon.ico', 'system', uploadedFile.path); + res.json([{ name: uploadedFile.name, url: imageObj.url }]); + } catch (err) { + next(err); + } finally { + file.delete(uploadedFile.path); } }; @@ -145,25 +143,24 @@ uploadsController.uploadTouchIcon = async function (req, res, next) { const allowedTypes = ['image/png']; const sizes = [36, 48, 72, 96, 144, 192, 512]; - if (validateUpload(res, uploadedFile, allowedTypes)) { - try { - const imageObj = await file.saveFileToLocal('touchicon-orig.png', 'system', uploadedFile.path); - // Resize the image into squares for use as touch icons at various DPIs - for (const size of sizes) { - /* eslint-disable no-await-in-loop */ - await image.resizeImage({ - path: uploadedFile.path, - target: path.join(nconf.get('upload_path'), 'system', `touchicon-${size}.png`), - width: size, - height: size, - }); - } - res.json([{ name: uploadedFile.name, url: imageObj.url }]); - } catch (err) { - next(err); - } finally { - file.delete(uploadedFile.path); + await validateUpload(uploadedFile, allowedTypes); + try { + const imageObj = await file.saveFileToLocal('touchicon-orig.png', 'system', uploadedFile.path); + // Resize the image into squares for use as touch icons at various DPIs + for (const size of sizes) { + /* eslint-disable no-await-in-loop */ + await image.resizeImage({ + path: uploadedFile.path, + target: path.join(nconf.get('upload_path'), 'system', `touchicon-${size}.png`), + width: size, + height: size, + }); } + res.json([{ name: uploadedFile.name, url: imageObj.url }]); + } catch (err) { + next(err); + } finally { + file.delete(uploadedFile.path); } }; @@ -172,15 +169,14 @@ uploadsController.uploadMaskableIcon = async function (req, res, next) { const uploadedFile = req.files.files[0]; const allowedTypes = ['image/png']; - if (validateUpload(res, uploadedFile, allowedTypes)) { - try { - const imageObj = await file.saveFileToLocal('maskableicon-orig.png', 'system', uploadedFile.path); - res.json([{ name: uploadedFile.name, url: imageObj.url }]); - } catch (err) { - next(err); - } finally { - file.delete(uploadedFile.path); - } + await validateUpload(uploadedFile, allowedTypes); + try { + const imageObj = await file.saveFileToLocal('maskableicon-orig.png', 'system', uploadedFile.path); + res.json([{ name: uploadedFile.name, url: imageObj.url }]); + } catch (err) { + next(err); + } finally { + file.delete(uploadedFile.path); } }; @@ -219,20 +215,16 @@ uploadsController.uploadOgImage = async function (req, res, next) { async function upload(name, req, res, next) { const uploadedFile = req.files.files[0]; - if (validateUpload(res, uploadedFile, allowedImageTypes)) { - const filename = name + path.extname(uploadedFile.name); - await uploadImage(filename, 'system', uploadedFile, req, res, next); - } + await validateUpload(uploadedFile, allowedImageTypes); + const filename = name + path.extname(uploadedFile.name); + await uploadImage(filename, 'system', uploadedFile, req, res, next); } -function validateUpload(res, uploadedFile, allowedTypes) { +async function validateUpload(uploadedFile, allowedTypes) { if (!allowedTypes.includes(uploadedFile.type)) { file.delete(uploadedFile.path); - res.json({ error: `[[error:invalid-image-type, ${allowedTypes.join(', ')}]]` }); - return false; + throw new Error(`[[error:invalid-image-type, ${allowedTypes.join(', ')}]]`); } - - return true; } async function uploadImage(filename, folder, uploadedFile, req, res, next) { diff --git a/src/views/modals/upload-file.tpl b/src/views/modals/upload-file.tpl index 537f6efd01..32e0569ba4 100644 --- a/src/views/modals/upload-file.tpl +++ b/src/views/modals/upload-file.tpl @@ -6,10 +6,10 @@