mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-16 12:46:04 +00:00
feat: disable webhook/websocket by default
This commit is contained in:
@@ -72,6 +72,11 @@ map_subscriptions_enabled =
|
||||
|> get_var_from_path_or_env("WANDERER_MAP_SUBSCRIPTIONS_ENABLED", "false")
|
||||
|> String.to_existing_atom()
|
||||
|
||||
websocket_events_enabled =
|
||||
config_dir
|
||||
|> get_var_from_path_or_env("WANDERER_WEBSOCKET_EVENTS_ENABLED", "false")
|
||||
|> String.to_existing_atom()
|
||||
|
||||
map_subscription_characters_limit =
|
||||
config_dir
|
||||
|> get_int_from_path_or_env("WANDERER_MAP_SUBSCRIPTION_CHARACTERS_LIMIT", 10_000)
|
||||
@@ -143,6 +148,7 @@ config :wanderer_app,
|
||||
wanderer_kills_service_enabled: wanderer_kills_service_enabled,
|
||||
wanderer_kills_base_url: wanderer_kills_base_url,
|
||||
map_subscriptions_enabled: map_subscriptions_enabled,
|
||||
websocket_events_enabled: websocket_events_enabled,
|
||||
map_connection_auto_expire_hours: map_connection_auto_expire_hours,
|
||||
map_connection_auto_eol_hours: map_connection_auto_eol_hours,
|
||||
map_connection_eol_expire_timeout_mins: map_connection_eol_expire_timeout_mins,
|
||||
|
||||
@@ -56,13 +56,12 @@ defmodule WandererApp.Application do
|
||||
{WandererApp.Character.TrackerPoolSupervisor, []},
|
||||
WandererApp.Character.TrackerManager,
|
||||
WandererApp.Map.Manager,
|
||||
WandererApp.ExternalEvents.MapEventRelay,
|
||||
WandererApp.ExternalEvents.WebhookDispatcher,
|
||||
WandererAppWeb.Presence,
|
||||
WandererAppWeb.Endpoint
|
||||
] ++
|
||||
maybe_start_corp_wallet_tracker(WandererApp.Env.map_subscriptions_enabled?()) ++
|
||||
maybe_start_kills_services()
|
||||
maybe_start_kills_services() ++
|
||||
maybe_start_websocket_services(WandererApp.Env.websocket_events_enabled?())
|
||||
|
||||
opts = [strategy: :one_for_one, name: WandererApp.Supervisor]
|
||||
|
||||
@@ -106,4 +105,15 @@ defmodule WandererApp.Application do
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_start_websocket_services(true) do
|
||||
Logger.info("Starting WebSocket/Webhook services...")
|
||||
|
||||
[
|
||||
WandererApp.ExternalEvents.MapEventRelay,
|
||||
WandererApp.ExternalEvents.WebhookDispatcher
|
||||
]
|
||||
end
|
||||
|
||||
defp maybe_start_websocket_services(_), do: []
|
||||
end
|
||||
|
||||
@@ -15,6 +15,7 @@ defmodule WandererApp.Env do
|
||||
def custom_route_base_url, do: get_key(:custom_route_base_url, "<CUSTOM_ROUTE_BASE_URL>")
|
||||
def invites, do: get_key(:invites, false)
|
||||
def map_subscriptions_enabled?, do: get_key(:map_subscriptions_enabled, false)
|
||||
def websocket_events_enabled?, do: get_key(:websocket_events_enabled, false)
|
||||
def public_api_disabled?, do: get_key(:public_api_disabled, false)
|
||||
|
||||
@decorate cacheable(
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
defmodule WandererAppWeb.UserSocket do
|
||||
use Phoenix.Socket
|
||||
require Logger
|
||||
|
||||
# External events channel for webhooks/WebSocket delivery
|
||||
channel "external_events:map:*", WandererAppWeb.MapEventsChannel
|
||||
|
||||
@impl true
|
||||
def connect(params, socket, connect_info) do
|
||||
# Check if websocket events are enabled
|
||||
unless WandererApp.Env.websocket_events_enabled?() do
|
||||
remote_ip = get_remote_ip(connect_info)
|
||||
Logger.info("WebSocket connection rejected - websocket events disabled from #{remote_ip}")
|
||||
:error
|
||||
else
|
||||
|
||||
# Extract API key from connection params
|
||||
# Client should connect with: /socket/websocket?api_key=<key>
|
||||
require Logger
|
||||
|
||||
|
||||
# Log connection attempt for security auditing
|
||||
remote_ip = get_remote_ip(connect_info)
|
||||
Logger.info("WebSocket connection attempt from #{remote_ip}")
|
||||
|
||||
|
||||
case params["api_key"] do
|
||||
api_key when is_binary(api_key) and api_key != "" ->
|
||||
# Store the API key in socket assigns for channel authentication
|
||||
@@ -21,23 +28,24 @@ defmodule WandererAppWeb.UserSocket do
|
||||
socket = socket
|
||||
|> assign(:api_key, api_key)
|
||||
|> assign(:remote_ip, remote_ip)
|
||||
|
||||
|
||||
Logger.info("WebSocket connection accepted from #{remote_ip}, pending channel authentication")
|
||||
{:ok, socket}
|
||||
|
||||
|
||||
_ ->
|
||||
# Require API key for external events
|
||||
Logger.warning("WebSocket connection rejected - missing API key from #{remote_ip}")
|
||||
:error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Extract remote IP from connection info
|
||||
defp get_remote_ip(connect_info) do
|
||||
case connect_info do
|
||||
%{peer_data: %{address: {a, b, c, d}}} ->
|
||||
"#{a}.#{b}.#{c}.#{d}"
|
||||
|
||||
|
||||
%{x_headers: headers} ->
|
||||
# Check for X-Forwarded-For or X-Real-IP headers (for proxied connections)
|
||||
Enum.find_value(headers, "unknown", fn
|
||||
@@ -45,7 +53,7 @@ defmodule WandererAppWeb.UserSocket do
|
||||
{"x-real-ip", ip} -> ip
|
||||
_ -> nil
|
||||
end)
|
||||
|
||||
|
||||
_ ->
|
||||
"unknown"
|
||||
end
|
||||
@@ -53,4 +61,4 @@ defmodule WandererAppWeb.UserSocket do
|
||||
|
||||
@impl true
|
||||
def id(_socket), do: nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
defmodule WandererAppWeb.Plugs.CheckWebsocketDisabled do
|
||||
import Plug.Conn
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
def call(conn, _opts) do
|
||||
if not WandererApp.Env.websocket_events_enabled?() do
|
||||
conn
|
||||
|> send_resp(403, "WebSocket events are disabled")
|
||||
|> halt()
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -180,6 +180,10 @@ defmodule WandererAppWeb.Router do
|
||||
plug WandererAppWeb.Plugs.CheckCharacterApiDisabled
|
||||
end
|
||||
|
||||
pipeline :api_websocket_events do
|
||||
plug WandererAppWeb.Plugs.CheckWebsocketDisabled
|
||||
end
|
||||
|
||||
pipeline :api_acl do
|
||||
plug WandererAppWeb.Plugs.CheckAclApiKey
|
||||
end
|
||||
@@ -240,6 +244,12 @@ defmodule WandererAppWeb.Router do
|
||||
resources "/signatures", MapSystemSignatureAPIController, except: [:new, :edit]
|
||||
get "/user-characters", MapAPIController, :show_user_characters
|
||||
get "/tracked-characters", MapAPIController, :show_tracked_characters
|
||||
end
|
||||
|
||||
# WebSocket events and webhook management endpoints (disabled by default)
|
||||
scope "/api/maps/:map_identifier", WandererAppWeb do
|
||||
pipe_through [:api, :api_map, :api_websocket_events]
|
||||
|
||||
get "/events", MapEventsAPIController, :list_events
|
||||
|
||||
# Webhook management endpoints
|
||||
|
||||
Reference in New Issue
Block a user