mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
[web] reject upload requests without a file path (#27156)
* [web] reject upload requests without a file path * [web] update copy on error message and link to contact form Co-authored-by: Kamal Arkinstall <kamal.arkinstall@overleaf.com> * [web] update copy: move dot to the end --------- Co-authored-by: Kamal Arkinstall <kamal.arkinstall@overleaf.com> GitOrigin-RevId: ba1ee81a91b046540caeb2f3f3da0e305611b35f
This commit is contained in:
@@ -66,7 +66,7 @@ function uploadProject(req, res, next) {
|
||||
async function uploadFile(req, res, next) {
|
||||
const timer = new metrics.Timer('file-upload')
|
||||
const name = req.body.name
|
||||
const path = req.file?.path
|
||||
const { path } = req.file
|
||||
const projectId = req.params.Project_id
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
let { folder_id: folderId } = req.query
|
||||
@@ -162,8 +162,14 @@ function multerMiddleware(req, res, next) {
|
||||
.status(422)
|
||||
.json({ success: false, error: req.i18n.translate('file_too_large') })
|
||||
}
|
||||
|
||||
return next(err)
|
||||
if (err) return next(err)
|
||||
if (!req.file?.path) {
|
||||
logger.info({ req }, 'missing req.file.path on upload')
|
||||
return res
|
||||
.status(400)
|
||||
.json({ success: false, error: 'invalid_upload_request' })
|
||||
}
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -867,6 +867,7 @@
|
||||
"invalid_password_too_similar": "",
|
||||
"invalid_regular_expression": "",
|
||||
"invalid_request": "",
|
||||
"invalid_upload_request": "",
|
||||
"invite": "",
|
||||
"invite_expired": "",
|
||||
"invite_more_collabs": "",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useTranslation, Trans } from 'react-i18next'
|
||||
import { FetchError } from '../../../../infrastructure/fetch-json'
|
||||
import RedirectToLogin from './redirect-to-login'
|
||||
import {
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
InvalidFilenameError,
|
||||
} from '../../errors'
|
||||
import DangerMessage from './danger-message'
|
||||
import getMeta from '@/utils/meta'
|
||||
|
||||
// TODO: Update the error type when we properly type FileTreeActionableContext
|
||||
export default function ErrorMessage({
|
||||
@@ -15,6 +16,7 @@ export default function ErrorMessage({
|
||||
error: string | Record<string, any>
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const { isOverleaf } = getMeta('ol-ExposedSettings')
|
||||
const fileNameLimit = 150
|
||||
|
||||
// the error is a string
|
||||
@@ -46,6 +48,22 @@ export default function ErrorMessage({
|
||||
</DangerMessage>
|
||||
)
|
||||
|
||||
case 'invalid_upload_request':
|
||||
if (!isOverleaf) {
|
||||
return (
|
||||
<DangerMessage>{t('generic_something_went_wrong')}</DangerMessage>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<DangerMessage>
|
||||
<Trans
|
||||
i18nKey="invalid_upload_request"
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
|
||||
components={[<a href="/contact" target="_blank" />]}
|
||||
/>
|
||||
</DangerMessage>
|
||||
)
|
||||
|
||||
case 'duplicate_file_name':
|
||||
return (
|
||||
<DangerMessage>
|
||||
|
||||
@@ -1111,6 +1111,7 @@
|
||||
"invalid_password_too_similar": "Password is too similar to parts of email address",
|
||||
"invalid_regular_expression": "Invalid regular expression",
|
||||
"invalid_request": "Invalid Request. Please correct the data and try again.",
|
||||
"invalid_upload_request": "The upload failed. If the problem persists, <0>let us know</0>.",
|
||||
"invalid_zip_file": "Invalid zip file",
|
||||
"invite": "Invite",
|
||||
"invite_expired": "The invite may have expired",
|
||||
|
||||
@@ -138,6 +138,47 @@ describe('ProjectStructureChanges', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when sending an upload request without a file', function () {
|
||||
describe('project', function () {
|
||||
it('should reject the request with status 400', async function () {
|
||||
const { response, body } = await owner.doRequest('POST', {
|
||||
uri: 'project/new/upload',
|
||||
json: true,
|
||||
formData: {
|
||||
name: 'foo',
|
||||
},
|
||||
})
|
||||
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(body).to.deep.equal({
|
||||
success: false,
|
||||
error: 'invalid_upload_request',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('file', function () {
|
||||
it('should reject the request with status 400', async function () {
|
||||
const projectId = await owner.createProject('foo', {
|
||||
template: 'blank',
|
||||
})
|
||||
const { response, body } = await owner.doRequest('POST', {
|
||||
uri: `project/${projectId}/upload`,
|
||||
json: true,
|
||||
formData: {
|
||||
name: 'foo.txt',
|
||||
},
|
||||
})
|
||||
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(body).to.deep.equal({
|
||||
success: false,
|
||||
error: 'invalid_upload_request',
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('uploading an empty zipfile', function () {
|
||||
let res
|
||||
|
||||
|
||||
Reference in New Issue
Block a user