Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Job-status WebSocket events appear to be broadcast to every connected client

オープン
#473 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
go, typescript

調査の方向性

Start with backend/main.go, backend/controllers/websocket.go, backend/controllers/job_queue.go, and frontend/src/components/HomePage.tsx to trace connection registration and job-status handling. Reproduce the suggested two-session flow if the local Docker/OAuth environment can be started, then confirm the intended ownership model with maintainers. Done means the intended behavior is decided and verified, with a two-connection regression test if scoping is required.

索引モデルが issue の本文から書いたものです。

説明

Summary

The frontend opens a job-status WebSocket at /ws?clientID=<uuid>, but the backend does not appear to read clientID (or any other user identifier) when registering the connection.

Authenticated sockets are stored in a process-wide clients map. JobStatusManager writes each JobStatus to every connection. JobStatus only contains a job name and a status string.

The home page treats incoming success events as belonging to the current user (toasts, and for most jobs a /tasks refetch).

The behavior is confirmed from the current source code, but has not yet been reproduced in two live authenticated sessions.

Current behavior (from source)

  1. GET /ws is handled by AuthenticatedWebSocketHandler (backend/main.go).
  2. After a valid session, the connection is stored as clients[ws] = true with no user/uuid key (backend/controllers/websocket.go).
  3. The query string (clientID) is not read in that handler.
  4. Mutation handlers enqueue work on GlobalJobQueue. AddJob / processJobs emit queued, in-progress, and success or failure via BroadcastJobStatus (backend/controllers/job_queue.go).
  5. JobStatusManager ranges over clients and WriteJSONs the same payload to each socket.
  6. Payload shape is only { "job": "...", "status": "..." }.
  7. HomePage.tsx connects with ws?clientID=${userInfo.uuid} and, on status === "success":
    • refetches tasks unless job === "Edit Task";
    • shows a success toast for Add Task, Edit Task, Complete Task, and Delete Task.

If two users have /home open, the source implies User B would receive User A's job-status messages and could toast/refetch as if the job were B's.

Expected behavior

I am not assuming a specific design. Two reasonable options:

  • Job-status events are only delivered to the user who queued the job (the unused clientID query param suggests this may have been intended), or
  • Global broadcast is intentional (e.g. single-user / self-hosted assumption).

Please confirm which of these is intended.

Technical evidence

Backend

  • backend/main.go — mux.HandleFunc("/ws", controllers.AuthenticatedWebSocketHandler(store))
  • backend/controllers/websocket.go
    • JobStatus — fields Job, Status only
    • AuthenticatedWebSocketHandler — session check, Upgrade, clients[ws] = true; no r.URL.Query() / clientID
    • BroadcastJobStatus — send on the global broadcast channel
    • JobStatusManager — for client := range clients { client.WriteJSON(jobStatus) }
  • backend/controllers/job_queue.go — AddJob / processJobs call BroadcastJobStatus with queued / in-progress / success / failure
  • Example job name: add_task.go uses Name: "Add Task"

Frontend

  • frontend/src/components/HomePage.tsx — getWebSocketURL(\ws?clientID=${userInfo.uuid}`)andsocket.onmessage`
  • frontend/src/components/utils/URLs.ts — getWebSocketURL (builds the URL; does not scope events)
  • frontend/src/components/HomeComponents/Tasks/hooks.ts — fetchTaskwarriorTasks (GET /tasks with the current page's user headers)

A GET /tasks from that path calls FetchTasksFromTaskwarrior (including rm -rf /root/.task and task sync) on the backend. That is only relevant if B actually refetches because of A's event.

Suggested reproduction (not yet run here)

  1. Two browsers/profiles, two logged-in users, both on /home.
  2. DevTools → Network → WS on both; confirm URLs like /ws?clientID=<A-uuid> and /ws?clientID=<B-uuid>.
  3. User A adds a task.
  4. Compare WS frames on A and B.
  5. Check whether B shows Task added successfully! and whether B issues GET /tasks with B's session headers (do not log encryption secrets).

Predicted frames if fan-out matches the source:

{"job":"Add Task","status":"queued"}
{"job":"Add Task","status":"in-progress"}
{"job":"Add Task","status":"success"}

Runtime reproduction limitation

This was not reproduced with two live authenticated browser sessions. The local environment could not start the full Docker/OAuth stack (Docker engine not running, no backend/.env / frontend/.env).

Please treat the two-user UI outcome as unverified until someone captures those WS frames.

Questions for maintainers

  1. Should /ws job-status events be limited to the user who queued the job, or is broadcasting to every authenticated socket intentional?
  2. If scoping is desired, should the unused clientID query parameter be the key, or should the handler use the session UUID instead (so the client cannot pick another id)?
  3. Should JobStatus include a user/job owner field, or should routing stay entirely server-side?

Possible direction (not implemented)

If global broadcast is not intended:

  • Associate each WebSocket with the session UUID at upgrade time (prefer session over the query string).
  • Send JobStatus only to matching connections (and include the owner on the Job if needed).
  • Keep HomePage toasts/refetch only for events that belong to that user.
  • Add a test with two connections and different ids that a job for A is not written to B.

Happy to help with a two-session capture or a patch once the intended behavior is clear.

主要言語
TypeScript
スター
37
フォーク
76
平均マージ
3日 7時間
マージ済み PR(30日)
2

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

CCExtractor/ccsync のほかの issue

CCExtractor/ccsync の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。