Skip to content

Commit 749962a

Browse files
authored
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/*`.
1 parent 3229b9a commit 749962a

File tree

6 files changed

+101
-16
lines changed

6 files changed

+101
-16
lines changed

packages/payload/src/collections/config/sanitize.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import type { LoginWithUsernameOptions } from '../../auth/types.js'
33
import type { Config, SanitizedConfig } from '../../config/types.js'
44
import type { CollectionConfig, SanitizedCollectionConfig, SanitizedJoins } from './types.js'
55

6+
import { authCollectionEndpoints } from '../../auth/endpoints/index.js'
67
import { getBaseAuthFields } from '../../auth/getAuthFields.js'
78
import { TimestampsRequired } from '../../errors/TimestampsRequired.js'
89
import { sanitizeFields } from '../../fields/config/sanitize.js'
910
import { fieldAffectsData } from '../../fields/config/types.js'
1011
import mergeBaseFields from '../../fields/mergeBaseFields.js'
12+
import { uploadCollectionEndpoints } from '../../uploads/endpoints/index.js'
1113
import { getBaseUploadFields } from '../../uploads/getBaseFields.js'
1214
import { deepMergeWithReactComponents } from '../../utilities/deepMerge.js'
1315
import { flattenAllFields } from '../../utilities/flattenAllFields.js'
@@ -58,6 +60,18 @@ export const sanitizeCollection = async (
5860
sanitized.endpoints = []
5961
}
6062

63+
if (sanitized.auth) {
64+
for (const endpoint of authCollectionEndpoints) {
65+
sanitized.endpoints.push(endpoint)
66+
}
67+
}
68+
69+
if (sanitized.upload) {
70+
for (const endpoint of uploadCollectionEndpoints) {
71+
sanitized.endpoints.push(endpoint)
72+
}
73+
}
74+
6175
for (const endpoint of defaultCollectionEndpoints) {
6276
sanitized.endpoints.push(endpoint)
6377
}

packages/payload/src/collections/endpoints/index.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { Endpoint } from '../../config/types.js'
22

3-
import { authCollectionEndpoints } from '../../auth/endpoints/index.js'
43
import { wrapInternalEndpoints } from '../../utilities/wrapInternalEndpoints.js'
54
import { countHandler } from './count.js'
65
import { createHandler } from './create.js'
@@ -12,15 +11,12 @@ import { findHandler } from './find.js'
1211
import { findByIDHandler } from './findByID.js'
1312
import { findVersionByIDHandler } from './findVersionByID.js'
1413
import { findVersionsHandler } from './findVersions.js'
15-
import { getFileHandler } from './getFile.js'
16-
import { getFileFromURLHandler } from './getFileFromURL.js'
1714
import { previewHandler } from './preview.js'
1815
import { restoreVersionHandler } from './restoreVersion.js'
1916
import { updateHandler } from './update.js'
2017
import { updateByIDHandler } from './updateByID.js'
2118

2219
export const defaultCollectionEndpoints: Endpoint[] = [
23-
...authCollectionEndpoints,
2420
...wrapInternalEndpoints([
2521
{
2622
handler: countHandler,
@@ -47,11 +43,6 @@ export const defaultCollectionEndpoints: Endpoint[] = [
4743
method: 'post',
4844
path: '/access/:id?',
4945
},
50-
{
51-
handler: getFileFromURLHandler,
52-
method: 'get',
53-
path: '/paste-url/:id?',
54-
},
5546
{
5647
handler: findVersionsHandler,
5748
method: 'get',
@@ -77,11 +68,6 @@ export const defaultCollectionEndpoints: Endpoint[] = [
7768
method: 'get',
7869
path: '/versions/:id',
7970
},
80-
{
81-
handler: getFileHandler,
82-
method: 'get',
83-
path: '/file/:filename',
84-
},
8571
{
8672
handler: previewHandler,
8773
method: 'get',
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { Endpoint } from '../../config/types.js'
2+
3+
import { wrapInternalEndpoints } from '../../utilities/wrapInternalEndpoints.js'
4+
import { getFileHandler } from './getFile.js'
5+
import { getFileFromURLHandler } from './getFileFromURL.js'
6+
7+
export const uploadCollectionEndpoints: Endpoint[] = wrapInternalEndpoints([
8+
{
9+
handler: getFileFromURLHandler,
10+
method: 'get',
11+
path: '/paste-url/:id?',
12+
},
13+
{
14+
handler: getFileHandler,
15+
method: 'get',
16+
path: '/file/:filename',
17+
},
18+
])

test/collections-rest/int.spec.ts

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import {
1717
errorOnHookSlug,
1818
methods,
1919
pointSlug,
20-
relationSlug,
2120
postsSlug,
21+
relationSlug,
2222
} from './config.js'
2323

2424
const filename = fileURLToPath(import.meta.url)
@@ -1454,7 +1454,7 @@ describe('collections-rest', () => {
14541454
for (let i = 0; i < 10; i++) {
14551455
await createPost({
14561456
number: i,
1457-
relationField: relatedDoc.id as string,
1457+
relationField: relatedDoc.id,
14581458
title: 'paginate-test',
14591459
})
14601460
}
@@ -1733,6 +1733,73 @@ describe('collections-rest', () => {
17331733
}
17341734
})
17351735
})
1736+
1737+
it('should not mount auth endpoints for collection without auth', async () => {
1738+
const authEndpoints = [
1739+
{
1740+
method: 'post',
1741+
path: '/forgot-password',
1742+
},
1743+
{
1744+
method: 'post',
1745+
path: '/login',
1746+
},
1747+
{
1748+
method: 'post',
1749+
path: '/logout',
1750+
},
1751+
{
1752+
method: 'post',
1753+
path: '/refresh-token',
1754+
},
1755+
{
1756+
method: 'post',
1757+
path: '/first-register',
1758+
},
1759+
{
1760+
method: 'post',
1761+
path: '/reset-password',
1762+
},
1763+
{
1764+
method: 'post',
1765+
path: '/unlock',
1766+
},
1767+
]
1768+
1769+
for (const endpoint of authEndpoints) {
1770+
const result = await restClient[endpoint.method.toUpperCase()](
1771+
`/${endpointsSlug}${endpoint.path}`,
1772+
)
1773+
1774+
expect(result.status).toBe(404)
1775+
const json = await result.json()
1776+
1777+
expect(json.message.startsWith('Route not found')).toBeTruthy()
1778+
}
1779+
})
1780+
1781+
it('should not mount upload endpoints for collection without auth', async () => {
1782+
const uploadEndpoints = [
1783+
{
1784+
method: 'get',
1785+
path: '/paste-url/some-id',
1786+
},
1787+
{
1788+
method: 'get',
1789+
path: '/file/some-filename.png',
1790+
},
1791+
]
1792+
1793+
for (const endpoint of uploadEndpoints) {
1794+
const result = await restClient[endpoint.method.toUpperCase()](
1795+
`/${endpointsSlug}${endpoint.path}`,
1796+
)
1797+
1798+
expect(result.status).toBe(404)
1799+
1800+
expect((await result.json()).message.startsWith('Route not found')).toBeTruthy()
1801+
}
1802+
})
17361803
})
17371804

17381805
async function createPost(overrides?: Partial<Post>) {

0 commit comments

Comments
 (0)