defmodule ToweropsWeb.Endpoint do use Phoenix.Endpoint, otp_app: :towerops use Absinthe.Phoenix.Endpoint # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. @session_options [ store: :cookie, key: "_towerops_key", signing_salt: "hrDZxLhd", encryption_salt: "vK3p8mNx", same_site: "Lax" ] socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]], longpoll: [connect_info: [session: @session_options]] socket "/socket/agent", ToweropsWeb.AgentSocket, websocket: [connect_info: [:peer_data]], longpoll: false socket "/socket/graphql", ToweropsWeb.GraphQLSocket, websocket: true, longpoll: false socket "/mobile/socket", ToweropsWeb.MobileSocket, websocket: [timeout: 60_000], longpoll: false # Serve at "/" the static files from "priv/static" directory. # # When code reloading is disabled (e.g., in production), # the `gzip` option is enabled to serve compressed # static files generated by running `phx.digest`. plug Plug.Static, at: "/", from: :towerops, gzip: not code_reloading?, only: ToweropsWeb.static_paths(), raise_on_missing_only: code_reloading? # Generated coverage rasters live outside priv/static so the path can point # at a shared NFS mount in production (see :coverage_storage_dir). Keep this # plug after the main static plug so /coverage URLs only fall through here. plug Plug.Static, at: "/coverage", from: Application.compile_env(:towerops, :coverage_storage_dir, {:towerops, "priv/static/coverage"}), gzip: false if Mix.env() == :dev do plug Tidewave end # Code reloading can be explicitly enabled under the # :code_reloader configuration of your endpoint. if code_reloading? do socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket plug Phoenix.LiveReloader plug Phoenix.CodeReloader plug Phoenix.Ecto.CheckRepoStatus, otp_app: :towerops end plug Phoenix.LiveDashboard.RequestLogger, param_key: "request_logger", cookie_key: "request_logger" plug Plug.RequestId plug ToweropsWeb.Plugs.RemoteIpLogger plug ToweropsWeb.Plugs.FilterNoisyLogs plug ToweropsWeb.Plugs.BruteForceProtection plug ToweropsWeb.Plugs.SecurityHeaders plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint], log: {__MODULE__, :telemetry_log_level, []} # Dynamic log level for Plug.Telemetry — suppresses logging for # health checks and uptime monitors (filtered by FilterNoisyLogs plug). def telemetry_log_level(conn) do if conn.private[:plug_skip_telemetry] do false else :info end end plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], body_reader: {ToweropsWeb.Endpoint.BodyReader, :read_body, []}, json_decoder: Phoenix.json_library() # Custom body reader that skips parsing for protobuf content type # and caches raw body for webhook signature verification. defmodule BodyReader do @moduledoc false def read_body(conn, opts) do case Plug.Conn.get_req_header(conn, "content-type") do ["application/x-protobuf" | _] -> # Don't parse protobuf, let the controller handle it {:ok, "", conn} _ -> case Plug.Conn.read_body(conn, opts) do {:ok, body, conn} -> conn = update_in(conn.private[:raw_body], &((&1 || "") <> body)) {:ok, body, conn} other -> other end end end end plug Plug.MethodOverride plug Plug.Head plug Plug.Session, @session_options # Enable SQL Sandbox metadata for LiveView tests # This allows LiveView processes to access the test's sandbox connection if Application.compile_env(:towerops, :sql_sandbox) do plug Phoenix.Ecto.SQL.Sandbox end plug ToweropsWeb.Plugs.MarkdownNegotiation plug ToweropsWeb.Router end