Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở
#473 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
45/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
go, typescript
Lĩnh vực
api, backend, frontend, security

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
TypeScript
Star
37
Fork
76
Merge trung bình
3 ngày 7 giờ
Pull request đã merge (30 ngày)
2

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của CCExtractor/ccsync

Tất cả issue của CCExtractor/ccsync

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.