Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#473 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
go, typescript

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
TypeScript
Stelle
37
Fork
76
Merge medio
3g 7h
PR unite (30g)
2

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di CCExtractor/ccsync

Tutte le issue di CCExtractor/ccsync

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.