diff --git a/CHANGELOG.md b/CHANGELOG.md index 955c1f066e..ff30a13565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.1] - 2026-02-13 + +### Fixed + +- 🔒 **Public sharing permission bypass fix.** Users with write access to knowledge bases, tools, skills, prompts, and models could previously see and use the "Public" sharing option regardless of their actual sharing permissions, and direct API calls could bypass frontend restrictions entirely; both frontend and backend now properly enforce `sharing.public_*` permissions, silently stripping public grants when users lack the corresponding permission. [#21356](https://github.com/open-webui/open-webui/issues/21356), [#21358](https://github.com/open-webui/open-webui/pull/21358) +- 🐘 **PostgreSQL analytics query fix.** The `get_chat_ids_by_model_id` function now works correctly with PostgreSQL by using `GROUP BY` with aggregate ordering instead of `DISTINCT` with non-aggregate `ORDER BY`, which PostgreSQL does not support. [Commit](https://github.com/open-webui/open-webui/commit/7bda6bf767d5d5c4dc1111465096a88e10b5030e) +- 🐘 **Skills PostgreSQL compatibility fix.** Skills now work correctly with PostgreSQL by using SQLAlchemy's native `JSON` column type instead of the custom `JSONField`, which caused compatibility issues. [Commit](https://github.com/open-webui/open-webui/commit/b4c3f54f9648c4232a0fd6557703ffa66fcf4caa) +- 🔍 **Knowledge tooltip z-index fix.** Knowledge base tooltips in the model editor no longer render behind other UI elements. [#21375](https://github.com/open-webui/open-webui/pull/21375) +- 📚 **Knowledge collection layout fix.** Knowledge collection names in the chat input menu no longer appear indented or truncated due to incorrect flex layout. [#21374](https://github.com/open-webui/open-webui/pull/21374) +- 🎯 **Model selector scroll position fix.** The model selector dropdown now correctly scrolls to and centers the currently selected model when opened, and resets scroll position when reopened. [Commit](https://github.com/open-webui/open-webui/commit/0b05b2fc7ed4c38af158707438ff404d1beb7c91) +- 🌐 **Translation updates.** Portuguese (Brazil) translations were updated. [#21345](https://github.com/open-webui/open-webui/pull/21345) + ## [0.8.0] - 2026-02-12 ### Added diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index e60c30cb62..d4b1e0a803 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -551,11 +551,9 @@ async def update_knowledge_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants("knowledge", id, form_data.access_grants, db=db) diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py index 666b7ced29..4befd4c200 100644 --- a/backend/open_webui/routers/models.py +++ b/backend/open_webui/routers/models.py @@ -545,11 +545,9 @@ async def update_model_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants( diff --git a/backend/open_webui/routers/notes.py b/backend/open_webui/routers/notes.py index 0c4ca0d2e3..cba4c3f4ca 100644 --- a/backend/open_webui/routers/notes.py +++ b/backend/open_webui/routers/notes.py @@ -356,11 +356,9 @@ async def update_note_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants("note", id, form_data.access_grants, db=db) diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index fea2497561..7356a2b0ba 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -653,10 +653,6 @@ async def unload_model( await get_all_models(request, user=user) models = request.app.state.OLLAMA_MODELS - # Canonicalize model name (if not supplied with version) - if ":" not in model_name: - model_name = f"{model_name}:latest" - if model_name not in models: raise HTTPException( status_code=400, detail=ERROR_MESSAGES.MODEL_NOT_FOUND(model_name) @@ -1353,9 +1349,6 @@ async def generate_chat_completion( detail="Model not found", ) - if ":" not in payload["model"]: - payload["model"] = f"{payload['model']}:latest" - url, url_idx = await get_ollama_url(request, payload["model"], url_idx) api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( str(url_idx), @@ -1432,9 +1425,6 @@ async def generate_openai_completion( del payload["metadata"] model_id = form_data.model - if ":" not in model_id: - model_id = f"{model_id}:latest" - model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: @@ -1466,9 +1456,6 @@ async def generate_openai_completion( detail="Model not found", ) - if ":" not in payload["model"]: - payload["model"] = f"{payload['model']}:latest" - url, url_idx = await get_ollama_url(request, payload["model"], url_idx) api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( str(url_idx), @@ -1518,9 +1505,6 @@ async def generate_openai_chat_completion( del payload["metadata"] model_id = completion_form.model - if ":" not in model_id: - model_id = f"{model_id}:latest" - model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: @@ -1556,9 +1540,6 @@ async def generate_openai_chat_completion( detail="Model not found", ) - if ":" not in payload["model"]: - payload["model"] = f"{payload['model']}:latest" - url, url_idx = await get_ollama_url(request, payload["model"], url_idx) api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( str(url_idx), diff --git a/backend/open_webui/routers/prompts.py b/backend/open_webui/routers/prompts.py index 8720ba1aa5..4d0bd07d0a 100644 --- a/backend/open_webui/routers/prompts.py +++ b/backend/open_webui/routers/prompts.py @@ -476,11 +476,9 @@ async def update_prompt_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants("prompt", prompt_id, form_data.access_grants, db=db) diff --git a/backend/open_webui/routers/skills.py b/backend/open_webui/routers/skills.py index a9a17f147a..2a51b993c8 100644 --- a/backend/open_webui/routers/skills.py +++ b/backend/open_webui/routers/skills.py @@ -352,11 +352,9 @@ async def update_skill_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants("skill", id, form_data.access_grants, db=db) diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py index 81194c2f4d..60fecbb6fc 100644 --- a/backend/open_webui/routers/tools.py +++ b/backend/open_webui/routers/tools.py @@ -566,11 +566,9 @@ async def update_tool_access_by_id( ) ): form_data.access_grants = [ - g for g in form_data.access_grants - if not ( - g.get("principal_type") == "user" - and g.get("principal_id") == "*" - ) + grant + for grant in form_data.access_grants + if not (grant.get("principal_type") == "user" and grant.get("principal_id") == "*") ] AccessGrants.set_access_grants("tool", id, form_data.access_grants, db=db) diff --git a/package-lock.json b/package-lock.json index 0a85159d06..b837771419 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-webui", - "version": "0.8.0", + "version": "0.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-webui", - "version": "0.8.0", + "version": "0.8.1", "dependencies": { "@azure/msal-browser": "^4.5.0", "@codemirror/lang-javascript": "^6.2.2", diff --git a/package.json b/package.json index 673bad49cc..a6e16abfa6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.8.0", + "version": "0.8.1", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", diff --git a/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte b/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte index 58bb6203c5..4783530777 100644 --- a/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte +++ b/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte @@ -836,8 +836,7 @@ bind:show={showAccessControlModal} bind:accessGrants={knowledge.access_grants} share={$user?.permissions?.sharing?.knowledge || $user?.role === 'admin'} - sharePublic={$user?.permissions?.sharing?.public_knowledge || - $user?.role === 'admin'} + sharePublic={$user?.permissions?.sharing?.public_knowledge || $user?.role === 'admin'} onChange={async () => { try { await updateKnowledgeAccessGrants(localStorage.token, id, knowledge.access_grants ?? []);