Commit Graph
63 Commits
Author SHA1 Message Date
Classic298andClaude Opus 4.7 f5f4b58958 fix: harden model profile image against SVG stored XSS (#25060)
ModelMeta.profile_image_url now runs validate_profile_image_url, rejecting SVG/script data URIs (matching UserUpdateForm and ChannelWebhookForm). The /model/profile/image endpoint enforces the PROFILE_IMAGE_ALLOWED_MIME_TYPES allowlist and sets X-Content-Type-Options: nosniff, so an SVG data URI can no longer be served inline on-origin. Closes the fourth profile-image XSS sink missed by the user and webhook fixes.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:41:55 -05:00
Timothy Jaeryang Baek 260ead64da refac 2026-05-21 14:01:57 +04:00
Timothy Jaeryang Baek 6d0295588e refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
Timothy Jaeryang Baek c951b4f262 chore: format 2026-05-11 02:29:13 +09:00
Classic298anddestination-one c66c273f62 fix: strip model params for read-only callers on per-id endpoint (#24525)
GET /api/v1/models/model?id=<model_id> at routers/models.py:412
returned the full model.model_dump() to any caller with read access,
including the params dict that holds the admin-curated system prompt
and other behavior config. The user-facing /api/models endpoint
already strips this via utils/models.py:170,210 with the comment
"Remove params to avoid exposing sensitive info", and /api/v1/models/list
gates by write permission so non-curators don't see the model in their
workspace listing at all. The per-id endpoint missed the same gate, so
a user with read-only access (e.g. granted access to use the model in
chat) could open /workspace/models/edit?id=<not-mine> in the browser
and read the system prompt verbatim from the network response, even
though saving was correctly blocked.

Compute write_access once at the top of the handler so it can serve
both the response-shape decision and the response field. When the
caller lacks write access, replace params with an empty dict in the
serialised response. Owners, admins under BYPASS_ADMIN_ACCESS_CONTROL,
and explicit write-grant holders still get the full payload so the
workspace edit UI keeps working for users who legitimately curate the
model.

Read-permission users continue to receive everything else they need to
chat with the model — the chat path resolves prompt/params server-side
from the stored ModelModel and never echoes them back through this
endpoint.

Reported by destination-one in GHSA-h2cw-7qw9-56xr.

Co-authored-by: destination-one <destination-one@users.noreply.github.com>
2026-05-11 00:59:08 +09:00
Classic298 cfd2888545 fix:image url validation and signout post (#24420)
* refac(routers): reject external URLs in profile/model image handlers

* refac(ui): centralize image URL validation in safeImageUrl helper

* refac(auths): make signout POST-only

* refac: gate external profile image redirect behind ENABLE_PROFILE_IMAGE_URL_FORWARDING

Restore the 302 redirect for external http(s) profile image URLs in
the user and model profile-image endpoints, but gate it behind a new
ENABLE_PROFILE_IMAGE_URL_FORWARDING env flag (default: True).

Existing deployments that rely on external profile image forwarding
continue to work unchanged.  Operators who want to suppress the
redirect (to prevent client-side IP/UA/Referer leaks) can set the
flag to False.
2026-05-09 07:33:31 +09:00
Timothy Jaeryang Baek 1dee67b64d refac 2026-05-09 01:21:17 +09:00
Timothy Jaeryang Baek 3d1e355df7 refac 2026-04-24 18:20:10 +09:00
Jacob Leksan f2cb63140c perf: redirect default model profile image to canonical static URL (#24015)
- Return 302 to /static/favicon.png instead of streaming the same PNG per
  model id so browsers can cache one asset for default avatars.
- Validate stored /static/ paths with decode, normpath, and /static
  prefix checks; invalid paths fall back to favicon.

Made-with: Cursor
2026-04-24 15:45:10 +09:00
Timothy Jaeryang BaekandClassic298 499129625b refac
Co-Authored-By: Classic298 <27028174+Classic298@users.noreply.github.com>
2026-04-17 13:33:11 +09:00
Classic298andClaude e396af3cc8 perf: reuse request db session in get_model_profile_image (#23796)
Pass the request-scoped AsyncSession into Models.get_model_by_id so the
endpoint no longer opens a fresh DB session on every call, avoiding an
extra connection acquisition per profile image request.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-17 11:28:19 +09:00
Timothy Jaeryang Baek 27169124f2 refac: async db 2026-04-12 14:22:11 -05:00
Timothy Jaeryang Baek 53eadb7df7 refac 2026-04-02 22:34:51 -05:00
Timothy Jaeryang Baek 4632f200a9 refac 2026-04-02 02:06:21 -05:00
Timothy Jaeryang Baek 90ca2e9b0f refac 2026-03-24 20:48:10 -05:00
Timothy Jaeryang Baek ade617efa8 refac 2026-03-24 04:49:48 -05:00
Timothy Jaeryang Baek de3317e26b refac 2026-03-17 17:58:01 -05:00
Timothy Jaeryang Baek 345f3e3559 refac 2026-02-25 15:15:59 -06:00
Timothy Jaeryang Baek 176f9a7816 refac 2026-02-23 16:01:03 -06:00
Timothy Jaeryang Baek 3d99de6771 enh: access grant level perms 2026-02-23 15:49:05 -06:00
Timothy Jaeryang Baek 3c54863414 refac 2026-02-22 15:41:10 -06:00
Timothy Jaeryang Baek 626d236d13 chore: format 2026-02-13 15:00:39 -06:00
Timothy Jaeryang Baek f027a01ab2 fix: direct model access control 2026-02-13 14:39:01 -06:00
Timothy Jaeryang Baek 589c4e64c1 refac 2026-02-13 13:56:29 -06:00
Timothy Jaeryang Baek 20de5a87da refac 2026-02-13 13:43:43 -06:00
Timothy Jaeryang Baek df6e38039f refac 2026-02-13 13:29:22 -06:00
Classic298 73776d54b8 fix: enforce public sharing permission checks across all resource types (#21358)
The sharePublic prop in editor components (Knowledge, Tools, Skills,
Prompts, Models) incorrectly included an "|| edit" / "|| write_access"
condition, allowing users with write access to see and use the "Public"
sharing option regardless of their actual public sharing permission.
Additionally, all backend access/update endpoints only verified write
authorization but did not check the corresponding sharing.public_*
permission, allowing direct API calls to bypass frontend restrictions
entirely.
Frontend: removed the edit/write_access bypass from sharePublic in all
five editor components so visibility is gated solely by the user's
sharing.public_* permission or admin role.
Backend: added has_public_read_access_grant checks to the access/update
endpoints in knowledge.py, tools.py, prompts.py, skills.py, models.py,
and notes.py. Public grants are silently stripped when the user lacks
the corresponding permission.
Fixes #21356
2026-02-13 11:22:32 -06:00
Timothy Jaeryang Baek 531ac70ce5 refac 2026-02-12 12:07:45 -06:00
Timothy Jaeryang Baek e3a8257690 refac 2026-02-10 15:41:11 -06:00
Timothy Jaeryang Baek f7406ff576 refac 2026-02-09 13:28:14 -06:00
Timothy Jaeryang Baek 7da37b4f66 refac 2026-01-12 21:41:23 +04:00
Classic298 cd5a38a694 feat: Models Atomic PR of #20243 (#20369)
* feat: Add read-only access support for Models

- Backend: Add write_access field to ModelAccessResponse
- Backend: Update /models/list to return ModelAccessListResponse
- Frontend: Display Read Only badge in Models list
- Frontend: Disable inputs and save button when no write access
- Frontend: Hide action buttons for read-only models

* fix: Handle ModelAccessListResponse format in getModels API

- Backend returns {items, total} instead of {data}
- Update getModels API to handle both formats for backward compatibility

* fix: Show read-only shared models in workspace list

- Backend: Change search_models permission from 'write' to 'read' to include shared models
- Backend: Keep user_id filter to only show owned/shared models (not all public)
- Frontend: Handle ModelAccessListResponse format in getModels API

* fix: Align Read Only badge inline with model name

* fix: Correct badge placement and fix syntax error

* fix: Resolve badge truncation in Models list

- Add w-full to flex container for proper spacing
- Wrap Badge in div to prevent truncation
- Match Knowledge.svelte badge pattern

* fix: Align Read Only badge with Knowledge.svelte pattern

- Match Knowledge.svelte structure for badge placement
- Actions only show when write_access or admin
- Remove w-full from container to prevent right-overflow

* fix: Return write_access from getModelById endpoint

fix: Return write_access from getModelById endpoint

- Use ModelAccessResponse instead of raw dict
- Remove inefficient getModels call in edit page

* revert

* fix

* fix

* fix
2026-01-05 23:37:41 +04:00
Timothy Jaeryang Baek ab7b97e21f refac 2026-01-05 22:12:49 +04:00
Timothy Jaeryang Baek bb821ab654 fix: revert model profile image cache 2026-01-05 21:49:54 +04:00
Classic298 a2e9263af0 fix: add explicit HTTPException for access control failures (#20280)
Fix implicit None returns in get_model_by_id, get_knowledge_by_id, get_tools_by_id, and get_prompt_by_command. Now properly returns 401 for access denied and 404 for not found instead of silently returning None.
2025-12-31 02:28:59 -05:00
Timothy Jaeryang Baek b1d0f00d8c refac/enh: db session sharing 2025-12-29 00:21:18 +04:00
landerrosette d29271184e fix: extract correct MIME type from base64 profile images (#20171) 2025-12-26 18:27:18 +04:00
G30 0eeda79048 fix: user group pagination reset and model image caching (#19959)
- Changed default sort order in 'Edit Group' modal to 'created_at' (newest first).
  Previously it sorted by group membership, causing toggled users to invisible jump
  to the top of the list (often changing pages). using a stable sort fixes this UX issue.
- Removed unnecessary `page = 1` reset in toggleMember function so admins
  don't lose their place when selecting multiple users.

Bug 2 - Model Image Display Bug:
- Added `Cache-Control: no-cache, must-revalidate` headers to the model profile
  image endpoint. This ensures that when a model avatar is updated, the browser
  fetches the new image instead of serving a stale cached version (favicon).

Fixes #19885
2025-12-21 05:04:45 -05:00
Timothy Jaeryang Baek 69722ba973 fix/refac: workspace shared model list 2025-11-25 06:32:27 -05:00
Timothy Jaeryang Baek 682013cee3 refac 2025-11-23 16:08:03 -05:00
Timothy Jaeryang Baek f5809165d7 refac 2025-11-23 15:28:07 -05:00
Timothy Jaeryang Baek b2034861ae refac: models workspace optimization 2025-11-22 23:20:51 -05:00
Timothy Jaeryang Baek 27b8775032 refac 2025-11-21 01:48:06 -05:00
Timothy Jaeryang Baek 6442871947 refac: profile_image_url optimization 2025-11-20 20:43:59 -05:00
Timothy Jaeryang Baek af1db82c7d refac: models endpoint 2025-11-19 03:18:16 -05:00
Classic298andClaude b4bc71d1bd feat: add granular import/export permissions for workspace items (#19242)
* feat: add granular import/export permissions for workspace items (#55)

Co-authored-by: Claude <noreply@anthropic.com>

* Fix permissions toggles not saving in EditGroupModal (#58)

Co-authored-by: Claude <noreply@anthropic.com>

* Fix permissions toggles not saving in EditGroupModal (#59)

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-17 18:25:23 -05:00
Timothy Jaeryang Baek 6681ff5cbd refac/fix: endpoint conflict 2025-11-02 18:41:57 -05:00
Timothy Jaeryang Baek 5043e7fc8c refac: introduce model id length limit 2025-10-08 16:54:06 -05:00
silentoplayz fe28097817 feat: refactor model import to a single backend endpoint
This refactors the model import functionality to improve performance and user experience by centralizing the logic on the backend.

Previously, the frontend would parse an imported JSON file and send an individual API request for each model, which was slow and inefficient.

This change introduces a new backend endpoint, `/api/v1/models/import`, that accepts a list of model objects. The frontend now reads the selected JSON file, parses it, and sends the entire payload to the backend in a single request. The backend then processes this list, creating or updating models as necessary.

This commit also includes the following fixes:
- Handles cases where the imported JSON contains models without `meta` or `params` fields by providing default empty values.
2025-09-28 18:49:42 -04:00
silentoplayz 231d182c35 feat: move JSON model import to backend
This moves the JSON model import functionality to the backend. Instead of the frontend parsing the JSON file and sending multiple requests, it now uploads the file to a new endpoint (/api/v1/models/import), which processes the file and imports the models. This improves efficiency and provides better user feedback.
2025-09-28 18:09:58 -04:00