Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server-side has() can only check for custom perms #1836

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/_partials/has-warning.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
> [!WARNING]
> When using `has()` **on the server-side** to check permissions, it only works with **custom permissions**, as [system permissions](/docs/organizations/roles-permissions#system-permissions) are not included in `auth.sessionClaims.orgs_permissions`. To check system permissions, verify the user's role instead.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The following example uses the [`has()`](/docs/references/nextjs/auth-object#has) helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationErrorResponse` utility is used to return an error.
The following example uses the [`has()`](/docs/references/backend/types/auth-object#has) helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationErrorResponse` utility is used to return an error.

```tsx {{ filename: 'app/api/reverification-example/route.ts' }}
import { auth, reverificationErrorResponse } from '@clerk/nextjs/server'
Expand Down
4 changes: 2 additions & 2 deletions docs/backend-requests/handling/js-backend-sdks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ To handle authenticated requests, use one of the following JS Backend SDKs.

## Clerk Express SDK

The `clerkMiddleware()` function checks the request's cookies and headers for a session JWT. If the user has a valid session, the `clerkMiddleware()` function attaches the [properties](/docs/references/nextjs/auth-object#auth-object-properties) of the authenticated user to the request object.
The `clerkMiddleware()` function checks the request's cookies and headers for a session JWT. If the user has a valid session, the `clerkMiddleware()` function attaches the [properties](/docs/references/backend/types/auth-object#auth-object-properties) of the authenticated user to the request object.

```js
import { clerkMiddleware } from '@clerk/express'
Expand All @@ -25,7 +25,7 @@ For more information on the Middleware functions and SDK features, see the [Expr

## Clerk Fastify SDK

The `clerkPlugin` checks the request's cookies and headers for a session JWT. If the user has a valid session, the `clerkPlugin` attaches the [properties](/docs/references/nextjs/auth-object#auth-object-properties) of the authenticated user to the request object.
The `clerkPlugin` checks the request's cookies and headers for a session JWT. If the user has a valid session, the `clerkPlugin` attaches the [properties](/docs/references/backend/types/auth-object#auth-object-properties) of the authenticated user to the request object.

```ts
import 'dotenv/config'
Expand Down
2 changes: 1 addition & 1 deletion docs/backend-requests/making/custom-session-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This guide will show you how to customize a session token to include additional

## Use the custom claims in your application

The [`Auth`](/docs/references/nextjs/auth-object) object includes a `sessionClaims` property that contains the custom claims you added to your session token. It's returned by the [`useAuth()`](/docs/references/react/use-auth) hook, the [`auth()`](/docs/references/nextjs/auth) and `getAuth()` helpers, and the `request` object in server contexts.
The [`Auth`](/docs/references/backend/types/auth-object) object includes a `sessionClaims` property that contains the custom claims you added to your session token. It's returned by the [`auth()`](/docs/references/nextjs/auth) and `getAuth()` helpers, and the `request` object in server contexts.

The following example demonstrates how to access the `fullName` and `primaryEmail` claims that were added to the session token in the last step. This examples are written for Next.js, but they can be adapted to other frameworks by using the appropriate method for accessing the `Auth` object.

Expand Down
2 changes: 1 addition & 1 deletion docs/backend-requests/making/jwt-templates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ To create a JWT template:

## Generate a JWT

To generate a token using a template, you can use the `getToken()` method. See the [reference documentation](/docs/references/nextjs/auth-object#get-token) for more information and example usage.
To generate a token using a template, you can use the `getToken()` method. See the [reference documentation](/docs/references/backend/types/auth-object#get-token) for more information and example usage.

## Complete example

Expand Down
2 changes: 1 addition & 1 deletion docs/customization/user-button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ With the above example, the `<UserButton />` menu items will be in the following

## Conditionally render menu items

To conditionally render menu items based on a user's role or permissions, you can use the [`has()`](/docs/references/nextjs/auth-object#has) helper function:
To conditionally render menu items based on a user's role or custom permissions, you can use the [`has()`](/docs/references/backend/types/auth-object#has) helper function:

<Tabs items={["Next.js", "Astro"]}>
<Tab>
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/force-organizations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ This guide will be written for Next.js applications using App Router, but the sa

### Detect an active organization

A session will always include an `orgId` via the [`Auth` object](/docs/references/nextjs/auth-object#auth-object-example-with-active-organization). This can be used to detect if a user has an active organization.
A session will always include an `orgId` via the [`Auth` object](/docs/references/backend/types/auth-object#auth-object-example-with-active-organization). This can be used to detect if a user has an active organization.

<Tabs items={["App Router Server Component", "App Router Client Component"]}>
<Tab>
Expand Down
8 changes: 4 additions & 4 deletions docs/guides/reverification.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ To implement reverification, you need to handle it both on the server- and clien

### Handle reverification server-side

To handle reverification server-side, use the [`auth.has()`](/docs/references/nextjs/auth-object#has) helper to check if the user has verified their credentials within a specific time period. Pass a [configuration](#supported-verification-configurations) to set the time period you would like. If the user hasn't verified their credentials within that time period, return either `reverificationError` or `reverificationErrorResponse`, depending on the framework you're using. Use the following tabs to see examples for different frameworks.
To handle reverification server-side, use the [`auth.has()`](/docs/references/backend/types/auth-object#has) helper to check if the user has verified their credentials within a specific time period. Pass a [configuration](#supported-verification-configurations) to set the time period you would like. If the user hasn't verified their credentials within that time period, return either `reverificationError` or `reverificationErrorResponse`, depending on the framework you're using. Use the following tabs to see examples for different frameworks.

<Tabs items={["Next.js Server Action", "Next.js Route Handler", "Ruby on Rails", "Other"]}>
<Tab>
The following example uses the [`has()`](/docs/references/nextjs/auth-object#has) helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationError` utility is used to return an error.
The following example uses the [`has()`](/docs/references/backend/types/auth-object#has) helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationError` utility is used to return an error.

```ts {{ filename: 'app/actions.ts' }}
'use server'
Expand All @@ -45,7 +45,7 @@ To handle reverification server-side, use the [`auth.has()`](/docs/references/ne
</Tab>

<Tab>
<Include src="_partials/reverification-route-handler" />
<Include src="_partials/nextjs/reverification-route-handler" />
</Tab>

<Tab>
Expand Down Expand Up @@ -189,7 +189,7 @@ The following example demonstrates how to use the [`useReverification()`](/docs/

## Supported reverification configurations

To define the time period of the reverification check, you can pass the one of the following configurations to the `has()` helper: `strict_mfa`, `strict`, `moderate`, and `lax`. See the [`has()` reference doc](/docs/references/nextjs/auth-object#check-authorization-params-with-custom-permissions) for more details.
To define the time period of the reverification check, you can pass the one of the following configurations to the `has()` helper: `strict_mfa`, `strict`, `moderate`, and `lax`. See the [`has()` reference doc](/docs/references/backend/types/auth-object#check-authorization-params-with-custom-permissions) for more details.

## Caveats

Expand Down
12 changes: 6 additions & 6 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1828,10 +1828,6 @@
"title": "`clerkMiddleware()`",
"wrap": false,
"href": "/docs/references/nextjs/clerk-middleware"
},
{
"title": "Auth Object",
"href": "/docs/references/nextjs/auth-object"
}
]
]
Expand Down Expand Up @@ -3182,8 +3178,8 @@
"items": [
[
{
"title": "`PaginatedResourceResponse`",
"href": "/docs/references/backend/types/paginated-resource-response"
"title": "`Auth` object",
"href": "/docs/references/backend/types/auth-object"
},
{
"title": "Backend `AllowlistIdentifier` object",
Expand Down Expand Up @@ -3220,6 +3216,10 @@
{
"title": "Backend `User` object",
"href": "/docs/references/backend/types/backend-user"
},
{
"title": "`PaginatedResourceResponse`",
"href": "/docs/references/backend/types/paginated-resource-response"
}
]
]
Expand Down
4 changes: 2 additions & 2 deletions docs/organizations/org-slugs-in-urls.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ This guide shows you how to add organization slugs to your app's URLs, configure

<Tabs items={["Server-side","Client-side"]}>
<Tab>
To get organization information on the server-side, access the [`Auth`](/docs/references/nextjs/auth-object) object. In Next.js apps, this object is returned by [`auth()`](/docs/references/nextjs/auth). In other frameworks, use the [`getAuth()`](/docs/references/nextjs/get-auth) helper to get the `Auth` object.
To get organization information on the server-side, access the [`Auth`](/docs/references/backend/types/auth-object) object. In Next.js apps, this object is returned by [`auth()`](/docs/references/nextjs/auth). In other frameworks, use the [`getAuth()`](/docs/references/nextjs/get-auth) helper to get the `Auth` object.

To access additional organization information like the organization name, you'll need to [customize the Clerk session token](/docs/backend-requests/making/custom-session-token) to include these details:

Expand All @@ -241,7 +241,7 @@ This guide shows you how to add organization slugs to your app's URLs, configure
```
1. Select **Save**.

You can now access the [`sessionClaims`](/docs/references/nextjs/auth-object#:~:text=sessionClaims)
Then, access the [`sessionClaims`](/docs/references/backend/types/auth-object#:~:text=sessionClaims)
on the `Auth` object.

```tsx {{ filename: 'app/orgs/[slug]/page.tsx', mark: [[23, 24]] }}
Expand Down
10 changes: 5 additions & 5 deletions docs/organizations/roles-permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ When a user creates a new organization, that user is automatically added as the

Permissions grant users privileged access to resources and operations, like creating and deleting. Clerk supports two types of permissions: System and Custom.

### System Permissions
### System permissions

Clerk has a set of System Permissions that power [Clerks Frontend API](/docs/reference/frontend-api){{ target: '_blank' }} and [organization-related Clerk components](/docs/components/overview#organization-components). They are a baseline set of permissions that Clerk needs to operate functionally.
Clerk has a set of system permissions that power [Clerk's Frontend API](/docs/reference/frontend-api){{ target: '_blank' }} and [organization-related Clerk components](/docs/components/overview#organization-components). They are a baseline set of permissions that Clerk needs to operate functionally.

Clerk’s System Permissions consist of the following:
Clerk's system permissions consist of the following:

- Manage Organization (`org:sys_profile:manage`)
- Delete Organization (`org:sys_profile:delete`)
Expand All @@ -58,10 +58,10 @@ Clerk’s System Permissions consist of the following:
- Read domains (`org:sys_domains:read`)
- Manage domains (`org:sys_domains:manage`)

You can assign these System Permissions to any role.
You can assign these system permissions to any role.

> [!WARNING]
> System permissions are not included in session claims. To do permission-checks on the server-side, you must [create custom permissions](/docs/organizations/create-roles-permissions).
> System permissions are not included in [session claims](/docs/backend-requests/resources/session-tokens#default-session-claims). To do permission-checks on the server-side, you must [create custom permissions](/docs/organizations/create-roles-permissions).

### Custom permissions

Expand Down
2 changes: 1 addition & 1 deletion docs/organizations/verified-domains.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Once a domain is added and verified in your organization, the user will have the

## Adding and verifying domains

Domains can be added and verified under an organization by any user with the `org:sys_domains:manage` permission. By default, admins have this permission. The easiest way to add and verify domains is by using Clerk's \[`<OrganizationSwitcher />`] component. In the **General** tab, there will be a **Verified domains** section.
Domains can be added and verified under an organization by any user with the `org:sys_domains:manage` permission. By default, admins have this permission. The easiest way to add and verify domains is by using Clerk's [`<OrganizationSwitcher />`](/docs/components/organization/organization-switcher) component. In the **General** tab, there will be a **Verified domains** section.

Domains can be verified through an email verification code sent to an email that matches the domain. If the user adding the domain already has a verified email using that domain in their account, the domain will be automatically verified.

Expand Down
4 changes: 2 additions & 2 deletions docs/organizations/verify-user-permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Clerk enables two broad approaches to role and permissions-based authorization:
- Use the [`<Protect>`](/docs/components/protect) component to prevent content from rendering if the active user is unauthorized.
- Call [`auth.protect()`](/docs/references/nextjs/auth#protect) to throw a `404` error if the active user is unauthorized.
1. If you would like more control over the response when a user is unauthorized, you can:
- Call the [`has()`](/docs/references/nextjs/auth-object#has) helper, which returns `false` if the active user lacks the role or permissions you're checking for. You can _choose_ how your app responds instead of immediately preventing content from rendering or throwing an error.
- Call the [`has()`](/docs/references/backend/types/auth-object#has) helper, which returns `false` if the active user lacks the role or permissions you're checking for. You can _choose_ how your app responds instead of immediately preventing content from rendering or throwing an error.

## Authorization in Client Components

Expand Down Expand Up @@ -261,7 +261,7 @@ The following examples work for both SSR and CSR.

## Authorization in Remix Loaders

The following example uses the [`has()`](/docs/references/nextjs/auth-object#has) helper to check if the user has the correct permission. If the user is not authorized, `has()` will return false, causing the loader to redirect the user to the `/request-access` route.
The following example uses the [`has()`](/docs/references/backend/types/auth-object#has) helper to check if the user has the correct permission. If the user is not authorized, `has()` will return false, causing the loader to redirect the user to the `/request-access` route.

<Tabs items={["Remix"]}>
<Tab>
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstarts/express.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Learn how to integrate Clerk into your Express backend for secure user authentic

## Add `clerkMiddleware()` to your application

The [`clerkMiddleware()`](/docs/references/express/overview#clerk-middleware) function checks the request's cookies and headers for a session JWT and, if found, attaches the [`Auth`](/docs/references/nextjs/auth-object#auth-object){{ target: '_blank' }} object to the `request` object under the `auth` key.
The [`clerkMiddleware()`](/docs/references/express/overview#clerk-middleware) function checks the request's cookies and headers for a session JWT and, if found, attaches the [`Auth`](/docs/references/backend/types/auth-object#auth-object){{ target: '_blank' }} object to the `request` object under the `auth` key.

```ts {{ filename: 'index.ts', mark: [3, 7] }}
import 'dotenv/config'
Expand Down
6 changes: 3 additions & 3 deletions docs/references/astro/clerk-middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const onRequest = clerkMiddleware((auth, context) => {

### Protect routes based on user authorization status

To protect routes based on user authorization status, use [`auth().has()`](/docs/references/nextjs/auth-object#has){{ target: '_blank' }} to check if the user has the required roles or permissions.
To protect routes based on user authorization status, use [`auth().has()`](/docs/references/backend/types/auth-object#has){{ target: '_blank' }} to check if the user has the required roles or custom permissions.

```tsx {{ filename: 'src/middleware.ts' }}
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'
Expand All @@ -68,8 +68,8 @@ export const onRequest = clerkMiddleware((auth, context) => {

// Restrict admin routes to users with specific permissions
if (
(isProtectedRoute(context.request) && !has({ permission: 'org:sys_memberships:manage' })) ||
!has({ permission: 'org:sys_domains_manage' })
(isProtectedRoute(context.request) && !has({ permission: 'org:admin:example1' })) ||
!has({ permission: 'org:admin:example2' })
) {
// Add logic to run if the user does not have the required permissions; for example, redirecting to the sign-in page
return redirectToSignIn()
Expand Down
2 changes: 1 addition & 1 deletion docs/references/astro/endpoints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function GET({ locals }) {

Clerk provides integrations with a number of popular databases.

To retrieve a token from a JWT template and fetch data from an external source, use the [`getToken()`](/docs/references/nextjs/auth-object#get-token){{ target: '_blank' }} method from the [`auth()` local](/docs/references/astro/locals), as shown in the following example:
To retrieve a token from a JWT template and fetch data from an external source, use the [`getToken()`](/docs/references/backend/types/auth-object#get-token){{ target: '_blank' }} method from the [`auth()` local](/docs/references/astro/locals), as shown in the following example:

```ts {{ filename: 'src/pages/api/route.ts' }}
export async function GET({ locals }) {
Expand Down
Loading
Loading