feat: document delete permissions + three-dots menu portal fix
- Add can_delete column to document_shares (migration 0005) - Inject x-user-is-admin header from backend proxy to doc-service - Add get_user_is_admin() dep in doc-service - Delete endpoint now allows: owner, admin, or group member with can_delete=true - Watch documents (user_id='watch') deletable by admins only - DocumentOut gains viewer_can_delete (computed per-request) - Share UI: 'Allow group members to delete' checkbox + trash badge on shares - RowActionsMenu dropdown portaled to document.body — fixes overflow-hidden clipping - Delete mutation onError handler — no more silent failures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -215,7 +215,7 @@ Auth: is_superuser OR member of group listed in manifest `required_groups`. Retu
|
||||
|
||||
### Documents and Categories — proxied
|
||||
|
||||
`/api/documents/*` and `/api/documents/categories/*` are transparently proxied to `doc-service:8001`. The backend injects `x-user-id` and `x-user-groups` headers. See `features/doc-service/CLAUDE.md` for the internal endpoint list.
|
||||
`/api/documents/*` and `/api/documents/categories/*` are transparently proxied to `doc-service:8001`. The backend injects `x-user-id`, `x-user-groups`, and `x-user-is-admin` headers. See `features/doc-service/CLAUDE.md` for the internal endpoint list.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -50,13 +50,16 @@ _HOP_BY_HOP = frozenset([
|
||||
_STRIP_RESPONSE = frozenset([*_HOP_BY_HOP, "content-length", "content-type"])
|
||||
|
||||
|
||||
async def _forward_headers(request: Request, user_id: str, db: AsyncSession) -> dict:
|
||||
async def _forward_headers(
|
||||
request: Request, user_id: str, is_admin: bool, db: AsyncSession
|
||||
) -> dict:
|
||||
headers = {
|
||||
k: v
|
||||
for k, v in request.headers.items()
|
||||
if k.lower() not in _HOP_BY_HOP
|
||||
}
|
||||
headers["x-user-id"] = user_id
|
||||
headers["x-user-is-admin"] = "true" if is_admin else "false"
|
||||
|
||||
# Inject the user's group memberships so the doc-service can evaluate
|
||||
# group-shared document access without querying the backend DB.
|
||||
@@ -78,7 +81,7 @@ async def proxy_documents(
|
||||
path: str = "",
|
||||
) -> Response:
|
||||
url = f"/documents/{path}" if path else "/documents"
|
||||
headers = await _forward_headers(request, str(current_user.id), db)
|
||||
headers = await _forward_headers(request, str(current_user.id), current_user.is_superuser, db)
|
||||
body = await request.body()
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user