Issue 7 tak cot - #12
Open
Tom-Neverwinter wants to merge 3 commits into
Open
Conversation
Read-only ingest only, as scoped with the user — no Phase 2 publish-to-TAK, no cert-upload UI. BYOS: God's Eye View never discovers or connects to a TAK network on its own; the layer reports UNAVAILABLE unless TAK_SERVER_HOST + a client cert/key are explicitly configured via env vars (local file paths only, never uploaded — see SECURITY.md/.env.example). Server: takProxy (vite.config.js) holds one mutual-TLS TCP connection (node:tls) to the configured TAK Server, verifying the server certificate (optionally against a private CA) and authenticating with the client cert/key. It never sends anything onto the stream — no presence announce, pure listen. Incoming CoT is decoded exclusively from events carrying a usable <point> (routes/polygons/shapes are out of scope for this pass); each object is dropped from the served snapshot the instant its own CoT `stale` time passes. In-memory only, no disk persistence, per the issue's "avoid persisting TAK position history" requirement. src/data/cotEvent.js holds the pure, XML-free helpers (MIL-STD-2525 affiliation decode, staleness check) shared by server and client. src/data/cotDecode.js isolates the XML parsing (fast-xml-parser, a new small dependency — CoT is real, attribute-heavy, escapable XML, not worth hand-rolling) and the TCP byte-stream event-boundary splitter (extractCotEvents), so neither reaches the browser bundle (confirmed via build output). src/data/takEvents.js polls the resulting snapshot and renders points colored by affiliation. Validated two ways beyond unit tests, since no real TAK Server was available: (1) a genuine end-to-end run against a local self-signed mutual-TLS server — verified client-cert auth, an event deliberately split across two TCP writes reassembling correctly, and both a full and a self-closing point-bearing CoT event decoding correctly; (2) the unconfigured path's UNAVAILABLE response on a live dev server. The specific handshake quirks of a real TAK Server implementation remain unverified — flag this if issues surface against one. Registered in main.js + layerState.js (token 'h'), voice/text aliases, BYOS entry in DATA_SOURCES.md (no attribution — not public data). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZFzxaNKiGGkq9V64Y9omb
- takEvents.js loadEvents(): never resolve `false` from update() — this is
the critical one, since manager.js's enable-lifecycle treats a `false`
update() as a fatal enable failure and bounces the toggle back off
(src/data/manager.js:908-909). The layer's "not configured" branch —
which is the DEFAULT state for this BYOS layer — was hitting exactly
that path, so simply enabling the layer without a TAK Server configured
never reached UNAVAILABLE; it just failed to enable at all. Also guard
against a destroy() racing an in-flight fetch (dataSource null-deref).
- cotDecode.js: `Number('')` is 0, not NaN, so a present-but-blank CoT
numeric attribute (e.g. `hae=""`) decoded as a fabricated 0 altitude/
heading instead of missing. Added a regression test.
- cotDecode.js: the detail-passthrough size cap compared JS string length
(UTF-16 code units) against a constant named for bytes; switched to
Buffer.byteLength so a non-ASCII callsign can't slip ~2x past the
intended budget.
- vite.config.js takProxy: renamed the buffer safety-cap constant to match
what it actually measures (characters, not bytes) rather than silently
fixing the discrepancy through an unwarranted per-chunk re-encoding
cost — the cap is a coarse backstop where 2x slop doesn't matter. Also
made the event-cache LRU eviction correct: a Map's set() on an existing
key doesn't move it, so without delete-then-set on update, "evict the
first key" was oldest-inserted, not oldest-seen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZFzxaNKiGGkq9V64Y9omb
- Security-relevant: TAK connection/cert-read errors were stored via Node's raw err.message and served verbatim through GET /api/tak/events — for common failures (ECONNREFUSED, ENOTFOUND, an fs ENOENT on the cert path) that message literally embeds the configured host:port or local file path, contradicting the documented guarantee (SECURITY.md, .env.example) that the browser never sees any of those. New sanitizeTakConnectionError() maps err.code (a stable, target-independent Node identifier) to a fixed generic message; the full raw detail still goes to the server's own console.warn log, just never crosses into the API response. Unit tested. - ensureTakConnection() could race the reconnect backoff: a client poll landing in the gap between a dropped connection (_takSocket = null) and its scheduled 15s reconnect timer firing would trigger an immediate extra connect attempt — re-reading cert/key files synchronously and opening a second TLS handshake, roughly doubling reconnect attempts against the remote TAK server during an outage. Now skips if a reconnect is already pending. - takEvents.js loadEvents(): add the missing response.ok check every sibling layer has, for the case where /api/tak/events itself returns a non-2xx response that isn't the deliberate "not configured" 503 shape (e.g. a fronting proxy in a non-dev deployment). - Removed a dead state.viewer assignment — this layer is a global, non-viewport-bounded feed and never reads it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZFzxaNKiGGkq9V64Y9omb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.