analytics/lib/plausible_web.ex
Adrian Gruntkowski 373d4dd665
Implement token-based sessions (#4463)
* Turn `Plausible.Auth.UserSession` into full schema

* Implement token based sessions and use them as default

* Ignore expired user sessions during retrieval from DB

* Implement plug bumping user session last used and timeout timestamps

* Implement Oban worker removing expired user sessions with grace period

* Implement legacy session conversion on touch, when applicable

* Update `UserAuth` moduledoc

* Extend `UserAuth` tests to account for db-backed session tokens

* Update CHANGELOG

* Add tests for `UserSessionTouch` plug

* Add test for `CleanUserSessions` worker

* Add logging of legacy session retrievals

* Use single update permitting stale records  when touching user session

* Don't fetch session and user for external API endpoints (/api/event too)

* Refactor `Users.with_subscription/1` and expose helper query

* Skip fetching session in legacy `SessionTimeoutPlug`

* Rely on user session assign from `AuthContext` in `SentryContext`

* Silence legacy session warnings in `UserSessionTouchTest`

* Rely on session assign from `AuthPlug` in `SuperAdminOnlyPlug`

* Change `UserAuth` to get session, user and last subscription in one go

* Avoid refetching user session in `AuthorizeSiteAccess` plug

* Fix code formatting

* Refactor `UserAuth.get_user_token/1` (h/t @aerosol)

* Remove bogus empty opts from `scope` declarations in router

* Only touch session once an hour and keep `user.last_seen` in sync

* Bring back logging of legacy token use
2024-09-03 11:34:37 +02:00

110 lines
2.5 KiB
Elixir

defmodule PlausibleWeb do
def live_view(opts \\ []) do
quote do
use Plausible
use Phoenix.LiveView, global_prefixes: ~w(x-)
use PlausibleWeb.Live.Flash
use PlausibleWeb.Live.AuthContext
unless :no_sentry_context in unquote(opts) do
use PlausibleWeb.Live.SentryContext
end
alias PlausibleWeb.Router.Helpers, as: Routes
alias Phoenix.LiveView.JS
end
end
def controller do
quote do
use Phoenix.Controller, namespace: PlausibleWeb
import Plug.Conn
import PlausibleWeb.ControllerHelpers
alias PlausibleWeb.Router.Helpers, as: Routes
end
end
def view do
quote do
use Phoenix.View,
root: "lib/plausible_web/templates",
namespace: PlausibleWeb
# Import convenience functions from controllers
import Phoenix.Controller, only: [view_module: 1]
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
use Phoenix.Component
import PlausibleWeb.ErrorHelpers
import PlausibleWeb.FormHelpers
import PlausibleWeb.Components.Generic
alias PlausibleWeb.Router.Helpers, as: Routes
end
end
def router do
quote do
use Phoenix.Router
import Plug.Conn
import Phoenix.Controller
end
end
def channel do
quote do
use Phoenix.Channel
end
end
def plugins_api_controller do
quote do
use Phoenix.Controller, namespace: PlausibleWeb.Plugins.API
import Plug.Conn
import PlausibleWeb.Router.Helpers
alias PlausibleWeb.Plugins.API.Schemas
alias PlausibleWeb.Plugins.API.Views
alias PlausibleWeb.Plugins.API.Errors
alias Plausible.Plugins.API
plug(OpenApiSpex.Plug.CastAndValidate, json_render_error_v2: true, replace_params: false)
use OpenApiSpex.ControllerSpecs
end
end
def plugins_api_view do
quote do
use Phoenix.View,
namespace: PlausibleWeb.Plugins.API,
root: ""
alias PlausibleWeb.Router.Helpers
import PlausibleWeb.Plugins.API.Views.Pagination, only: [render_metadata_links: 4]
end
end
def open_api_schema do
quote do
require OpenApiSpex
alias OpenApiSpex.Schema
alias PlausibleWeb.Plugins.API.Schemas
end
end
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
defmacro __using__([{which, opts}]) when is_atom(which) do
apply(__MODULE__, which, [List.wrap(opts)])
end
end