Commit graph

69 commits

Author SHA1 Message Date
Graham McInitre
243a98df77 fix: security hardening and query performance improvements
- Session cookie: add encryption_salt and secure flag to endpoint
- CSP: remove unsafe-eval from script-src directive
- /metrics: wrap PromEx endpoint behind rate-limited pipeline
- LiveView signing_salt: move to env var in production config
- LiveView performance: defer heavy aggregation queries past initial mount
- SQL: replace correlated subquery with DISTINCT ON in get_heard_by_stations
2026-07-21 10:13:30 -05:00
6eda1c0290
fix: resolve 19 bugs across Elixir, JS/TS, and config
Critical:
- Remove :protected from WeatherCache ETS (conflicted with :public)
- Register Aprsme.ReplayRegistry in supervision tree
- Route :continue_replay dead message to :start_replay handler
- Add 5000ms timeout to unbounded :rpc.call calls
- Fix falsy lat/lng check rejecting valid 0 coordinates

Medium:
- Fix live_reload pattern (temp_web -> aprsme_web)
- Remove duplicate ecto_repos config
- Make DB SSL configurable via DB_SSL env var
- Track sizeCheckTimeout on self for cleanup in destroyed()
- Wrap pushEvent calls in try/catch
- Remove unused size variable in marker cluster icon
- Capture touch coords at touchstart instead of stale TouchEvent
- Demote console.log to console.debug in production code
- Add catch-all to normalize_bounds preventing GenServer crash

Style:
- Add missing @impl true annotations in is.ex
- Improve migration failure error message
- Use textContent instead of innerHTML for error messages
- Use proper type for longPressTimer instead of any
2026-06-21 11:47:07 -05:00
a377847122
chore: remove unused deps, replace resend with custom Swoosh adapter, fix test isolation
Remove faker, floki, igniter, ecto_psql_extras (zero usages), exvcr
(zero usages), and resend. Replace resend with Aprsme.Swoosh.ResendAdapter
using the already-present req dependency. Frees 23 packages total from
the lockfile including hackney, certifi, and the tesla dependency chain.

Fix two pre-existing test isolation bugs:
- signal_handler_test called the real ShutdownHandler.shutdown() via SIGTERM
  simulation without restoring state, causing page_controller_test to see
  shutting_down: true and return 503
- page_controller_test setup now resets ShutdownHandler state defensively
2026-04-24 13:04:18 -05:00
d87ef4dac5
config: disable SSL/TLS for database connections
Adds ssl: false to Repo config to disable database encryption.
2026-03-22 11:27:44 -05:00
df6431c899
Disable database SSL/TLS encryption
Removed DATABASE_SSL and DATABASE_SSL_VERIFY environment variable
handling and SSL configuration from database connection settings.
2026-03-20 12:56:38 -05:00
fcff4fa6f0
Fix packet retention config to read env var at runtime
Move packet_retention_days configuration from config.exs (compile-time)
to runtime.exs so it properly reads the PACKET_RETENTION_DAYS environment
variable at runtime instead of baking in the default value during build.

This fixes the issue where the app was using 7 days retention despite
PACKET_RETENTION_DAYS being set to 1 in the deployment, causing disk
to fill up with 54GB of old partition data.
2026-02-25 16:23:22 -06:00
781fdd88a3
Remove dead modules, unused deps, and commented-out code
Delete 5 unused modules: Presence (untracked), LiveView ShutdownHandler
(unused mixin), RateLimiterWrapper (pointless delegation), Passcode
(only used by own test), MapLive.Utils (pure delegates).

Fix ShutdownHandler to not call deleted Presence. Inline ParamUtils
at call sites. Remove cachex dep and 27 stale entries from mix.lock.
Clean commented-out Exq/Redis config from application.ex.
2026-02-20 08:09:22 -06:00
75ceb73607
Fix Erlang clustering: use IP-based node names with DNS strategy
DNSSRV strategy resolves to IP-based names but nodes were named by
pod name, causing connection failures. Switch to DNS strategy with
IP-based node naming so libcluster discovery matches actual node names.
2026-02-19 16:01:20 -06:00
87dc076220
Set APRS_HOST and APRS_PASSWORD env vars
Connect to 204.110.191.232 instead of the default dallas.aprs2.net.
runtime.exs now reads APRS_HOST (over APRS_SERVER) and APRS_PASSWORD
(over APRS_PASSCODE) so both naming conventions work.
2026-02-18 12:16:54 -06:00
26d93e36c7
fix: remove Exq dependency and Redis job queue
- Remove Exq dependency from mix.exs and application config
- Remove all Exq configuration from config files (config.exs, dev.exs, runtime.exs, test.exs)
- Update CleanupScheduler to run cleanup tasks directly using Task.start instead of queuing jobs
- Update PacketCleanupWorker documentation to remove Exq references
- Cleanup functionality preserved but now runs in supervised Tasks instead of job queue

This resolves the Redis connection error on startup by eliminating the dependency on external job queues.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 16:24:59 -05:00
93e19ff517
Remove all external dependencies and Sentry integration
- Remove external Leaflet CDN links from info page (now uses vendor bundles)
- Remove all Sentry error tracking integration:
  - Remove sentry dependency from mix.exs
  - Remove Sentry plugs from endpoint.ex
  - Remove Sentry logger handler from application.ex
  - Remove Sentry configs from dev.exs and prod.exs
  - Remove Sentry domains from runtime.exs check_origin
  - Remove Sentry JavaScript initialization
  - Delete sentry_filter.ex module
  - Remove Sentry loader script from root layout

The application now loads all assets locally with no external runtime dependencies.
2025-10-03 12:53:47 -05:00
af4b58f61d
Fix code formatting 2025-07-29 10:32:32 -05:00
31b2f8fb91
Add SSL support for PostgreSQL connections
- Add DATABASE_SSL and DATABASE_SSL_VERIFY environment variables
- Configure Postgrex to use SSL with optional certificate verification
- Allow connecting to PostgreSQL with self-signed certificates
2025-07-29 10:31:04 -05:00
6fdd39dc0e
Fix CI test failures and configuration issues
- Simplify APRS_PORT parsing to avoid syntax errors
- Disable Exq properly in test environment to prevent startup issues
- Disable Prometheus telemetry in test mode to avoid port conflicts
- Update telemetry module to conditionally start Prometheus metrics

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 13:51:43 -05:00
f8e075319e
Fix APRS_PORT parsing error causing application crashes
- Add robust integer parsing for APRS_PORT environment variable
- Fallback to default port 14580 if parsing fails
- Prevents crashes when environment variables contain unexpected values

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 13:45:56 -05:00
844c1b0a6c
Add configurable APRS_PORT environment variable support
- Make APRS-IS port configurable via APRS_PORT environment variable
- Defaults to 14580 (filtered port) if not specified
- Allows switching to 10152 (unfiltered port) for full packet stream

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 12:50:15 -05:00
1596e95eba
format 2025-07-27 11:16:16 -05:00
028dd50372
Fix Redis authentication error - don't send empty password
- Only include password in Exq config if it's not empty
- Prevents "ERR AUTH <password>" error when Redis has no authentication
- Build config dynamically to exclude empty password field

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:33:45 -05:00
46f68f3070
Fix syntax error in runtime.exs Redis configuration
- Wrap String.to_integer in try/rescue block properly
- Fix CompileError caused by rescue clause inside case statement
- Ensures runtime.exs can compile and load Redis configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:18:32 -05:00
269ec5a070
Fix Exq Redis configuration for Kubernetes deployment
- Parse REDIS_URL environment variable in runtime.exs
- Extract host, port, password, and database from Redis URL
- Use same Redis configuration parsing as RedisCache module
- Fixes CrashLoopBackOff caused by Exq trying to connect to localhost

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 10:08:50 -05:00
4fcdc33ec0
Fix database parameters for PgBouncer compatibility
Remove PostgreSQL session-specific parameters that are not supported
by PgBouncer connection pooling. Keep only application_name parameter
which is passed through properly.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 10:32:53 -05:00
c85b907ab7
Move Redis PubSub config to runtime initialization
- Remove static Redis PubSub configuration from runtime.exs
- Add dynamic pubsub_config/0 function in application.ex
- Configure PubSub adapter based on cluster_enabled and REDIS_URL at startup
- Ensures proper initialization order for distributed deployments

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 10:10:55 -05:00
194ff0006f
Add Redis PubSub support for distributed clustering
Configures Phoenix.PubSub.Redis adapter when clustering is enabled
and REDIS_URL environment variable is set. This allows PubSub
messages to be shared across Elixir nodes in a distributed
deployment, enabling proper real-time updates in multi-node setups.

- Add phoenix_pubsub_redis dependency (~> 3.0)
- Configure Redis adapter in runtime.exs for production
- Set pool size to 10 for better performance
- Include node name in Redis configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-26 10:05:41 -05:00
46ece7aa38
Add Cloudflare Insights domain to allowed origins
Add https://static.cloudflareinsights.com to check_origin list
to resolve CORS errors from Cloudflare Web Analytics beacon.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 13:36:16 -05:00
777acc2700
Use DNSSRV strategy for StatefulSet clustering
Switch to Kubernetes.DNSSRV strategy which is specifically designed
for StatefulSets and uses DNS SRV records for node discovery.

This strategy:
- Doesn't require Kubernetes API permissions (no RBAC needed)
- Automatically filters out the current node
- Works with StatefulSet stable DNS names
- Uses SRV records from the headless service

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 12:37:37 -05:00
93397badbd
Switch to Kubernetes strategy with hostname mode for StatefulSet
Based on libcluster documentation, StatefulSets should use the standard
Kubernetes strategy with mode: :hostname, not the DNS strategy.

This properly discovers pods using their stable hostnames and filters
out the current node from connection attempts.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 12:35:27 -05:00
620144164f
Switch to Kubernetes.DNS strategy for StatefulSet clustering
The DNSPoll strategy was attempting to connect to IPs instead of DNS names.
Kubernetes.DNS strategy is specifically designed for StatefulSet deployments
and will properly discover pods using their stable DNS names.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 12:23:49 -05:00
16e675745f
Use DNSPoll strategy for Kubernetes clustering 2025-07-25 12:05:12 -05:00
94fad09901
Use Gossip strategy for Kubernetes clustering 2025-07-25 11:53:01 -05:00
187a607563
Fix Kubernetes node naming for distributed Erlang clustering 2025-07-25 11:47:37 -05:00
4804bd16be
Add distributed Erlang clustering for single APRS-IS connection
Implement leader election to ensure only one APRS-IS connection across
multiple Kubernetes replicas. This prevents duplicate packet processing
and respects APRS-IS usage policies.

Key changes:
- Add leader election using :global registry
- Create connection manager for dynamic APRS-IS management
- Implement packet distribution from leader to all nodes
- Add Kubernetes headless service for node discovery
- Configure DNS-based clustering with libcluster
- Update deployment to support 3 replicas with clustering

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 10:30:29 -05:00
ce5724973c
Add 10.0.19.221 to allowed origins
Allow HTTP connections from internal IP 10.0.19.221 for k3s cluster access

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:51:58 -05:00
c52adc8a9e
Fix Phoenix check_origin configuration and add kubectl docs
- Replace invalid wildcard domains (*.aprs.me) with explicit origins
- Phoenix doesn't support wildcard syntax in check_origin
- Added specific domains for aprs.me, sentry.io, and openstreetmap.org
- Updated CLAUDE.md with kubectl commands for debugging k3s deployment

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-24 19:40:15 -05:00
992f0f6483
csp change 2025-07-24 11:40:44 -05:00
ae8c74afbe
try vector tiles 2025-07-24 10:54:31 -05:00
234fc2010f
Implement critical performance optimizations and error handling
This commit introduces several major performance improvements and adds
robust error handling for malformed HTTP requests:

Performance Optimizations:
- Add database migration with BRIN indexes for time-series data and partial
  indexes for recent queries, significantly improving query performance
- Create global StreamingPacketsPubSub system for real-time packet distribution
  with geographic bounds filtering using ETS for fast lookups
- Refactor PacketConsumer to use Stream module for memory-efficient processing,
  preventing memory accumulation during batch operations
- Implement dedicated BroadcastTaskSupervisor pool for async broadcast operations,
  preventing GenServer blocking on I/O
- Increase database connection pool from 25 to 45 (production) and 15 to 30 (dev)
  for better concurrency support

Error Handling:
- Add SentryFilter to prevent Bandit.HTTPError from missing Host headers from
  cluttering Sentry (common with bots/scanners)
- Configure custom 400 Bad Request error handling
- Filter out common bot/scanner paths from error reporting

All changes include comprehensive test coverage following TDD practices.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 18:19:49 -05:00
1da12cf665
Remove debug console.log statements from JavaScript files
- Removed all console.log debugging statements from app.js (theme changes, chart rendering)
- Removed all console.log statements from map.ts (map initialization, data processing)
- Removed all console.debug statements from map_helpers.ts
- Removed all console.debug statements from map_fixes.ts
- Kept essential console.error and console.warn statements for error handling
- Reduced bundle size by ~1.4kb

This cleanup removes unnecessary debug output while maintaining error reporting
for production debugging via console.error and Sentry.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:37:05 -05:00
1c7a1754ee
add sentry-cdn to cors 2025-07-18 15:23:58 -05:00
8d5bfe127e
add email 2025-07-18 10:15:09 -05:00
53c88d2262
postgres optimization 2025-07-15 09:06:40 -05:00
062489f5ae
staging fix 2025-07-11 13:19:24 -05:00
711d92ebb6
performance improvements 2025-07-08 10:03:52 -05:00
79fa7713ab
release tweak 2025-07-07 17:12:42 -05:00
5a6a782a03
release tweak 2025-07-07 17:09:46 -05:00
06efe1834b
release tweak 2025-07-07 17:02:17 -05:00
0bee0228b0
fix app name 2025-07-07 16:46:48 -05:00
9a6f649157
add clustering 2025-07-07 16:41:14 -05:00
b2f9352091
parser hash fix 2025-07-07 13:02:49 -05:00
294a54823d
cors fix 2025-07-05 13:03:27 -05:00
172da7d393
upgrade more with modern phoenix 2025-07-05 08:04:06 -05:00