feat(api): add personal API tokens and enhance webhook integration UI
- Add ApiToken model with SHA-256 hashed storage and usage tracking - Create API token CRUD endpoints (POST/GET/DELETE /api/api-tokens/) - Add Bearer token authentication to require_login decorator - Exempt Bearer-authenticated requests from CSRF validation - Add API tokens management page with create/revoke/copy UI - Enhance webhook integration type with detailed explanation and code snippets - Add navigation links (desktop + mobile) to API tokens page - Include 19 tests covering CRUD, auth resolution, and utility functions - Create migration 024_add_api_tokens Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -109,6 +109,13 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
||||
|
||||
# Validate for state-changing methods on non-exempt paths.
|
||||
if request.method in CSRF_PROTECTED_METHODS and request.url.path not in CSRF_EXEMPT_PATHS:
|
||||
# Bearer-authenticated requests (API tokens) are exempt from CSRF
|
||||
# because the token itself acts as proof of intent — it cannot be
|
||||
# injected by a cross-site request from a browser.
|
||||
auth_header = request.headers.get("authorization", "")
|
||||
if auth_header.startswith("Bearer "):
|
||||
return await call_next(request)
|
||||
|
||||
submitted_token = await self._get_submitted_token(request)
|
||||
if not submitted_token or not secrets.compare_digest(csrf_token, submitted_token):
|
||||
logger.warning(f"[SECURITY] CSRF_VALIDATION_FAILED method={request.method} path={request.url.path}")
|
||||
|
||||
Reference in New Issue
Block a user