fix: upload and auth endpoints are mounted for all collections (#11231)

This PR ensures, that collections that don't have `auth: true` don't
mount authentication related endpoints like `/me`, the same for uploads.
Additionally, moves upload-related endpoints to `uploads/endpoints/*`.
This commit is contained in:
Sasha
2025-02-17 21:11:40 +02:00
committed by GitHub
parent 3229b9a4a6
commit 749962a1db
6 changed files with 101 additions and 16 deletions

View File

@@ -0,0 +1,75 @@
// @ts-strict-ignore
import { fileTypeFromFile } from 'file-type'
import fsPromises from 'fs/promises'
import { status as httpStatus } from 'http-status'
import path from 'path'
import type { PayloadHandler } from '../../config/types.js'
import { APIError } from '../../errors/APIError.js'
import { checkFileAccess } from '../../uploads/checkFileAccess.js'
import { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'
import { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'
import { getRequestCollection } from '../../utilities/getRequestEntity.js'
import { headersWithCors } from '../../utilities/headersWithCors.js'
export const getFileHandler: PayloadHandler = async (req) => {
const collection = getRequestCollection(req)
const filename = req.routeParams.filename as string
if (!collection.config.upload) {
throw new APIError(
`This collection is not an upload collection: ${collection.config.slug}`,
httpStatus.BAD_REQUEST,
)
}
const accessResult = await checkFileAccess({
collection,
filename,
req,
})
if (accessResult instanceof Response) {
return accessResult
}
if (collection.config.upload.handlers?.length) {
let customResponse = null
for (const handler of collection.config.upload.handlers) {
customResponse = await handler(req, {
doc: accessResult,
params: {
collection: collection.config.slug,
filename,
},
})
}
if (customResponse instanceof Response) {
return customResponse
}
}
const fileDir = collection.config.upload?.staticDir || collection.config.slug
const filePath = path.resolve(`${fileDir}/${filename}`)
const stats = await fsPromises.stat(filePath)
const data = streamFile(filePath)
const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)
let headers = new Headers()
headers.set('Content-Type', fileTypeResult.mime)
headers.set('Content-Length', stats.size + '')
headers = collection.config.upload?.modifyResponseHeaders
? collection.config.upload.modifyResponseHeaders({ headers })
: headers
return new Response(data, {
headers: headersWithCors({
headers,
req,
}),
status: httpStatus.OK,
})
}