Skip to content

Commit c9a8aa0

Browse files
authored
refactor: replace generic Error('Unauthorized') with UnauthorizedError (#14879)
Refactors all auth checks to throw `UnauthorizedError` instead of the generic `Error('Unauthorized')`. This ensures consistent unauthorized errors being thrown
1 parent dcecc46 commit c9a8aa0

File tree

4 files changed

+18
-8
lines changed

4 files changed

+18
-8
lines changed

docs/local-api/server-functions.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,11 @@ Using server functions helps prevent direct exposure of Local API operations to
512512
Example of restricting access based on user role:
513513

514514
```ts
515+
import { UnauthorizedError } from 'payload'
516+
515517
export async function deletePost(postId, user) {
516518
if (!user || user.role !== 'admin') {
517-
throw new Error('Unauthorized')
519+
throw new UnauthorizedError()
518520
}
519521

520522
const payload = await getPayload({ config })

packages/payload/src/utilities/canAccessAdmin.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { PayloadRequest } from '../types/index.js'
22

3+
import { UnauthorizedError } from '../errors/UnauthorizedError.js'
4+
35
/**
46
* Protects admin-only routes, server functions, etc.
57
* The requesting user must either:
@@ -19,11 +21,11 @@ export const canAccessAdmin = async ({ req }: { req: PayloadRequest }) => {
1921
const canAccess = await adminAccessFn({ req })
2022

2123
if (!canAccess) {
22-
throw new Error('Unauthorized')
24+
throw new UnauthorizedError()
2325
}
2426
// Match the user collection to the global admin config
2527
} else if (adminUserSlug !== incomingUserSlug) {
26-
throw new Error('Unauthorized')
28+
throw new UnauthorizedError()
2729
}
2830
} else {
2931
const hasUsers = await req.payload.find({
@@ -35,7 +37,7 @@ export const canAccessAdmin = async ({ req }: { req: PayloadRequest }) => {
3537

3638
// If there are users, we should not allow access because of `/create-first-user`
3739
if (hasUsers.docs.length) {
38-
throw new Error('Unauthorized')
40+
throw new UnauthorizedError()
3941
}
4042
}
4143
}

packages/ui/src/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { deepMerge, type Field, type FieldState, type ServerFunction } from 'payload'
1+
import {
2+
deepMerge,
3+
type Field,
4+
type FieldState,
5+
type ServerFunction,
6+
UnauthorizedError,
7+
} from 'payload'
28

39
import { getClientConfig } from '../../../utilities/getClientConfig.js'
410
import { getClientSchemaMap } from '../../../utilities/getClientSchemaMap.js'
@@ -44,7 +50,7 @@ export const _internal_renderFieldHandler: ServerFunction<
4450
// eslint-disable-next-line @typescript-eslint/require-await
4551
> = async ({ field: fieldArg, initialValue, path, req, schemaPath }) => {
4652
if (!req.user) {
47-
throw new Error('Unauthorized')
53+
throw new UnauthorizedError()
4854
}
4955

5056
const [entityType, entitySlug, ...fieldPath] = schemaPath.split('.')

packages/ui/src/utilities/buildFormState.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type {
77
ServerFunction,
88
} from 'payload'
99

10-
import { canAccessAdmin, formatErrors } from 'payload'
10+
import { canAccessAdmin, formatErrors, UnauthorizedError } from 'payload'
1111
import { getSelectMode, reduceFieldsToValues } from 'payload/shared'
1212

1313
import { fieldSchemasToFormState } from '../forms/fieldSchemasToFormState/index.js'
@@ -70,7 +70,7 @@ export const buildFormStateHandler: ServerFunction<
7070
}
7171

7272
if (err.message === 'Unauthorized') {
73-
throw new Error('Unauthorized')
73+
throw new UnauthorizedError()
7474
}
7575

7676
return formatErrors(err)

0 commit comments

Comments
 (0)