Initial commit

This commit is contained in:
2026-04-17 23:26:01 +00:00
commit 2ea4ca5d52
409 changed files with 63459 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
---
title: Use @request Context in API Rules
impact: CRITICAL
impactDescription: Enables dynamic, user-aware access control
tags: api-rules, security, request-context, authentication
---
## Use @request Context in API Rules
The `@request` object provides access to the current request context including authenticated user, request body, query parameters, and headers. Use it to build dynamic access rules.
**Incorrect (hardcoded or missing auth checks):**
```javascript
// No authentication check
const collection = {
listRule: '', // Anyone can see everything
createRule: '' // Anyone can create
};
// Hardcoded user ID (never do this)
const collection = {
listRule: 'owner = "specific_user_id"' // Only one user can access
};
```
**Correct (using @request context):**
```javascript
// Check if user is authenticated
createRule: '@request.auth.id != ""'
// Check ownership via auth record
listRule: 'owner = @request.auth.id'
viewRule: 'owner = @request.auth.id'
updateRule: 'owner = @request.auth.id'
deleteRule: 'owner = @request.auth.id'
// Access auth record fields
// IMPORTANT: If using custom role fields, ensure update rules prevent
// users from modifying their own role: @request.body.role:isset = false
listRule: '@request.auth.role = "admin"'
listRule: '@request.auth.verified = true'
// Validate request body on create/update
createRule: '@request.auth.id != "" && @request.body.owner = @request.auth.id'
// Prevent changing certain fields
updateRule: 'owner = @request.auth.id && @request.body.owner:isset = false'
// WARNING: Query parameters are user-controlled and should NOT be used
// for authorization decisions. Use them only for optional filtering behavior
// where the fallback is equally safe.
// listRule: '@request.query.publicOnly = "true" || owner = @request.auth.id'
// The above is UNSAFE - users can bypass ownership by adding ?publicOnly=true
// Instead, use separate endpoints or server-side logic for public vs. private views.
listRule: 'owner = @request.auth.id || public = true' // Use a record field, not query param
// Access nested auth relations
listRule: 'team.members ?= @request.auth.id'
```
**Available @request fields:**
| Field | Description |
|-------|-------------|
| `@request.auth.id` | Authenticated user's ID (empty string if not authenticated) |
| `@request.auth.*` | Any field from auth record (role, verified, email, etc.) |
| `@request.body.*` | Request body fields (create/update only) |
| `@request.query.*` | URL query parameters |
| `@request.headers.*` | Request headers |
| `@request.method` | HTTP method (GET, POST, etc.) |
| `@request.context` | Request context: `default`, `oauth2`, `otp`, `password`, `realtime`, `protectedFile` |
**Body field modifiers:**
```javascript
// Check if field is being set
updateRule: '@request.body.status:isset = false' // Can't change status
// Check if field changed from current value
updateRule: '@request.body.owner:changed = false' // Can't change owner
// Get length of array/string
createRule: '@request.body.tags:length <= 5' // Max 5 tags
```
Reference: [PocketBase API Rules](https://pocketbase.io/docs/api-rules-and-filters/#available-fields)