diff --git a/agent/dashboard/thread_api.py b/agent/dashboard/thread_api.py index 0cebc979..6e5cdfbb 100644 --- a/agent/dashboard/thread_api.py +++ b/agent/dashboard/thread_api.py @@ -428,7 +428,7 @@ async def get_dashboard_thread( raise HTTPException(404, "thread not found") from exc metadata = thread.get("metadata") if isinstance(thread.get("metadata"), dict) else {} - _assert_thread_owner(metadata, login, email) + is_owner = _user_owns_thread(metadata, login, email) messages: list[dict[str, Any]] = [] try: @@ -454,7 +454,7 @@ async def get_dashboard_thread( else None ), ) - if mark_viewed and status != "running": + if mark_viewed and is_owner and status != "running": metadata = await _mark_thread_viewed( client, thread_id, diff --git a/tests/test_dashboard_thread_api_activity.py b/tests/test_dashboard_thread_api_activity.py index 7393d397..60b18d66 100644 --- a/tests/test_dashboard_thread_api_activity.py +++ b/tests/test_dashboard_thread_api_activity.py @@ -83,6 +83,24 @@ async def test_get_dashboard_thread_marks_finished_thread_viewed(monkeypatch) -> assert client.threads.thread["metadata"]["last_viewed_run_id"] == "run-1" +async def test_get_dashboard_thread_readable_by_non_owner(monkeypatch) -> None: + client = FakeClient( + { + "source": "slack", + "github_login": "octocat", + "latest_run_id": "run-1", + "latest_run_status": "success", + }, + "success", + ) + monkeypatch.setattr(thread_api, "langgraph_client", lambda: client) + + result = await thread_api.get_dashboard_thread("tid", "someone-else") + + assert result["status"] == "finished" + assert "last_viewed_run_id" not in client.threads.thread["metadata"] + + async def test_get_dashboard_thread_skips_mark_viewed_when_disabled(monkeypatch) -> None: client = FakeClient( {