| defmodule PlausibleWeb.Endpoint do |
| use Plausible |
| use Sentry.PlugCapture |
| use Phoenix.Endpoint, otp_app: :plausible |
|
|
| on_ce do |
| plug :maybe_handle_acme_challenge |
| plug :maybe_force_ssl, Plug.SSL.init(_no_opts = []) |
| end |
|
|
| @session_options [ |
| |
| key: "_plausible_key", |
| store: :cookie, |
| signing_salt: "I45i0SKHEku2f3tJh6y4v8gztrb/eG5KGCOe/o/AwFb7VHeuvDOn7AAq6KsdmOFM", |
| |
| max_age: 60 * 60 * 24 * 365 * 5, |
| extra: "SameSite=Lax" |
| |
| ] |
|
|
| socket("/live", Phoenix.LiveView.Socket, |
| websocket: [ |
| check_origin: true, |
| connect_info: [ |
| :peer_data, |
| :uri, |
| :user_agent, |
| session: {__MODULE__, :runtime_session_opts, []} |
| ] |
| ] |
| ) |
|
|
| |
| |
| |
| |
| plug(PlausibleWeb.TrackerPlug) |
| plug(PlausibleWeb.Favicon) |
|
|
| static_paths = ~w(css js images favicon.ico) |
|
|
| static_paths = |
| on_ee do |
| |
| static_paths |
| else |
| static_paths ++ ["robots.txt"] |
| end |
|
|
| static_compression = |
| if ce?() do |
| [brotli: true, gzip: true] |
| else |
| [gzip: false] |
| end |
|
|
| plug( |
| Plug.Static, |
| [at: "/", from: :plausible, only: static_paths] ++ static_compression |
| ) |
|
|
| |
| |
| if code_reloading? do |
| socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) |
| plug(Phoenix.LiveReloader) |
| plug(Phoenix.CodeReloader) |
| end |
|
|
| plug(Plug.RequestId) |
| plug(PromEx.Plug, prom_ex_module: Plausible.PromEx) |
| plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint], log: false) |
|
|
| plug(Plug.Parsers, |
| parsers: [:urlencoded, :multipart, :json], |
| pass: ["*/*"], |
| json_decoder: Phoenix.json_library() |
| ) |
|
|
| plug(Sentry.PlugContext) |
|
|
| plug(Plug.MethodOverride) |
| plug(Plug.Head) |
|
|
| plug(:runtime_session) |
|
|
| plug(CORSPlug) |
| plug(PlausibleWeb.Router) |
|
|
| def secure_cookie?, do: config!(:secure_cookie) |
|
|
| def websocket_url() do |
| config!(:websocket_url) |
| end |
|
|
| def runtime_session(conn, _opts) do |
| Plug.run(conn, [{Plug.Session, runtime_session_opts()}]) |
| end |
|
|
| def runtime_session_opts() do |
| session_options = |
| on_ee do |
| |
| |
| |
| |
| Keyword.put(@session_options, :domain, host()) |
| |> Keyword.put(:key, "_plausible_#{Application.fetch_env!(:plausible, :environment)}") |
| else |
| |
| @session_options |
| end |
|
|
| session_options |
| |> Keyword.put(:secure, secure_cookie?()) |
| end |
|
|
| defp config!(key) do |
| :plausible |
| |> Application.fetch_env!(__MODULE__) |
| |> Keyword.fetch!(key) |
| end |
|
|
| on_ce do |
| require SiteEncrypt |
| @behaviour SiteEncrypt |
| @force_https_key {:plausible, :force_https} |
| @allow_acme_challenges_key {:plausible, :allow_acme_challenges} |
|
|
| @doc false |
| def force_https do |
| :persistent_term.put(@force_https_key, true) |
| end |
|
|
| @doc false |
| def allow_acme_challenges do |
| :persistent_term.put(@allow_acme_challenges_key, true) |
| end |
|
|
| defp maybe_handle_acme_challenge(conn, _opts) do |
| if :persistent_term.get(@allow_acme_challenges_key, false) do |
| SiteEncrypt.AcmeChallenge.call(conn, _endpoint = __MODULE__) |
| else |
| conn |
| end |
| end |
|
|
| defp maybe_force_ssl(conn, opts) do |
| if :persistent_term.get(@force_https_key, false) do |
| Plug.SSL.call(conn, opts) |
| else |
| conn |
| end |
| end |
|
|
| @impl SiteEncrypt |
| def handle_new_cert, do: :ok |
|
|
| @doc false |
| def app_env_config do |
| |
| Application.get_env(:plausible, _endpoint = __MODULE__, []) |
| end |
|
|
| @impl SiteEncrypt |
| def certification do |
| selfhost_config = Application.fetch_env!(:plausible, :selfhost) |
| config = Keyword.fetch!(selfhost_config, :site_encrypt) |
|
|
| domain = Keyword.fetch!(config, :domain) |
| email = Keyword.fetch!(config, :email) |
| db_folder = Keyword.fetch!(config, :db_folder) |
| directory_url = Keyword.fetch!(config, :directory_url) |
|
|
| SiteEncrypt.configure( |
| mode: :auto, |
| log_level: :notice, |
| client: :certbot, |
| domains: [domain], |
| emails: [email], |
| db_folder: db_folder, |
| directory_url: directory_url |
| ) |
| end |
| end |
| end |
|
|