mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 01:22:15 +03:00
improve first launch experience for self-hosters (#2357)
* first launch * dynamic children, wait for repo * remove wait_for_repo and app env manipulations * don't mention free trial in self-hosted pages * add changelog * assigns[:is_selfhost] -> @is_selfhost * better changelog wording * rm admin_user, admin_email, admin_pwd from app env * rm DISABLE_AUTH * redirect / to /login when not authenticated * remove TODO * Update lib/plausible_web/controllers/page_controller.ex Co-authored-by: Uku Taht <Uku.taht@gmail.com> * format Co-authored-by: Uku Taht <Uku.taht@gmail.com>
This commit is contained in:
parent
0e91ae9b58
commit
0b7870dc4d
@ -39,6 +39,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Manually lock and unlock enterprise users plausible/analytics#2197
|
||||
- ARM64 support for docker images plausible/analytics#2103
|
||||
- Add support for international domain names (IDNs) plausible/analytics#2034
|
||||
- Allow self-hosters to register an account on first launch
|
||||
|
||||
### Fixed
|
||||
- Plausible script does not prevent default if it's been prevented by an external script [plausible/analytics#1941](https://github.com/plausible/analytics/issues/1941)
|
||||
|
@ -6,8 +6,6 @@ CRON_ENABLED=false
|
||||
LOG_LEVEL=warn
|
||||
ENVIRONMENT=test
|
||||
MAILER_ADAPTER=Bamboo.TestAdapter
|
||||
ADMIN_USER_EMAIL=admin@email.com
|
||||
ADMIN_USER_PWD=fakepassword
|
||||
ENABLE_EMAIL_VERIFICATION=true
|
||||
SELFHOST=false
|
||||
SITE_LIMIT=3
|
||||
|
@ -58,9 +58,6 @@ db_url =
|
||||
|
||||
db_socket_dir = get_var_from_path_or_env(config_dir, "DATABASE_SOCKET_DIR")
|
||||
|
||||
admin_user = get_var_from_path_or_env(config_dir, "ADMIN_USER_NAME")
|
||||
admin_email = get_var_from_path_or_env(config_dir, "ADMIN_USER_EMAIL")
|
||||
|
||||
super_admin_user_ids =
|
||||
get_var_from_path_or_env(config_dir, "ADMIN_USER_IDS", "")
|
||||
|> String.split(",")
|
||||
@ -71,7 +68,6 @@ super_admin_user_ids =
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
admin_pwd = get_var_from_path_or_env(config_dir, "ADMIN_USER_PWD")
|
||||
env = get_var_from_path_or_env(config_dir, "ENVIRONMENT", "prod")
|
||||
mailer_adapter = get_var_from_path_or_env(config_dir, "MAILER_ADAPTER", "Bamboo.SMTPAdapter")
|
||||
mailer_email = get_var_from_path_or_env(config_dir, "MAILER_EMAIL", "hello@plausible.local")
|
||||
@ -135,10 +131,10 @@ geolite2_country_db =
|
||||
ip_geolocation_db = get_var_from_path_or_env(config_dir, "IP_GEOLOCATION_DB", geolite2_country_db)
|
||||
geonames_source_file = get_var_from_path_or_env(config_dir, "GEONAMES_SOURCE_FILE")
|
||||
|
||||
disable_auth =
|
||||
config_dir
|
||||
|> get_var_from_path_or_env("DISABLE_AUTH", "false")
|
||||
|> String.to_existing_atom()
|
||||
if System.get_env("DISABLE_AUTH") do
|
||||
require Logger
|
||||
Logger.warn("DISABLE_AUTH env var is no longer supported")
|
||||
end
|
||||
|
||||
enable_email_verification =
|
||||
config_dir
|
||||
@ -193,9 +189,6 @@ disable_cron =
|
||||
|> String.to_existing_atom()
|
||||
|
||||
config :plausible,
|
||||
admin_user: admin_user,
|
||||
admin_email: admin_email,
|
||||
admin_pwd: admin_pwd,
|
||||
environment: env,
|
||||
mailer_email: mailer_email,
|
||||
super_admin_user_ids: super_admin_user_ids,
|
||||
@ -206,9 +199,8 @@ config :plausible,
|
||||
domain_blacklist: domain_blacklist
|
||||
|
||||
config :plausible, :selfhost,
|
||||
disable_authentication: disable_auth,
|
||||
enable_email_verification: enable_email_verification,
|
||||
disable_registration: if(!disable_auth, do: disable_registration, else: false)
|
||||
disable_registration: disable_registration
|
||||
|
||||
config :plausible, PlausibleWeb.Endpoint,
|
||||
url: [scheme: base_url.scheme, host: base_url.host, path: base_url.path, port: base_url.port],
|
||||
|
@ -1,5 +1,7 @@
|
||||
defmodule Plausible.Release do
|
||||
use Plausible.Repo
|
||||
require Logger
|
||||
|
||||
@app :plausible
|
||||
@start_apps [
|
||||
:postgrex,
|
||||
@ -7,24 +9,13 @@ defmodule Plausible.Release do
|
||||
:ecto
|
||||
]
|
||||
|
||||
def init_admin do
|
||||
prepare()
|
||||
|
||||
{admin_email, admin_user, admin_pwd} =
|
||||
validate_admin(
|
||||
{Application.get_env(:plausible, :admin_email),
|
||||
Application.get_env(:plausible, :admin_user),
|
||||
Application.get_env(:plausible, :admin_pwd)}
|
||||
)
|
||||
|
||||
case Plausible.Auth.find_user_by(email: admin_email) do
|
||||
nil ->
|
||||
{:ok, _} = Plausible.Auth.create_user(admin_user, admin_email, admin_pwd)
|
||||
IO.puts("Admin user created successful!")
|
||||
|
||||
_ ->
|
||||
IO.puts("Admin user already exists. I won't override, bailing")
|
||||
@spec selfhost? :: boolean
|
||||
def selfhost? do
|
||||
Application.fetch_env!(@app, :is_selfhost)
|
||||
end
|
||||
|
||||
def should_be_first_launch? do
|
||||
selfhost?() and not (_has_users? = Repo.exists?(Plausible.Auth.User))
|
||||
end
|
||||
|
||||
def migrate do
|
||||
@ -81,18 +72,6 @@ defmodule Plausible.Release do
|
||||
|
||||
##############################
|
||||
|
||||
defp validate_admin({nil, nil, nil}) do
|
||||
random_user = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
|
||||
random_pwd = :crypto.strong_rand_bytes(20) |> Base.encode64() |> binary_part(0, 20)
|
||||
random_email = "#{random_user}@#{System.get_env("HOST")}"
|
||||
IO.puts("generated admin user/password: #{random_email} / #{random_pwd}")
|
||||
{random_email, random_user, random_pwd}
|
||||
end
|
||||
|
||||
defp validate_admin({admin_email, admin_user, admin_password}) do
|
||||
{admin_email, admin_user, admin_password}
|
||||
end
|
||||
|
||||
defp repos do
|
||||
Application.fetch_env!(@app, :ecto_repos)
|
||||
end
|
||||
|
@ -1,7 +1,7 @@
|
||||
defmodule PlausibleWeb.AuthController do
|
||||
use PlausibleWeb, :controller
|
||||
use Plausible.Repo
|
||||
alias Plausible.Auth
|
||||
alias Plausible.{Auth, Release}
|
||||
require Logger
|
||||
|
||||
plug PlausibleWeb.RequireLoggedOutPlug
|
||||
@ -24,23 +24,41 @@ defmodule PlausibleWeb.AuthController do
|
||||
:activate_form
|
||||
]
|
||||
|
||||
plug :maybe_disable_registration when action in [:register_form, :register]
|
||||
plug :assign_is_selfhost
|
||||
|
||||
defp maybe_disable_registration(conn, _opts) do
|
||||
selfhost_config = Application.get_env(:plausible, :selfhost)
|
||||
disable_registration = Keyword.fetch!(selfhost_config, :disable_registration)
|
||||
first_launch? = Release.should_be_first_launch?()
|
||||
|
||||
cond do
|
||||
first_launch? ->
|
||||
conn
|
||||
|
||||
disable_registration in [:invite_only, true] ->
|
||||
conn |> redirect(to: Routes.auth_path(conn, :login_form)) |> halt()
|
||||
|
||||
true ->
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_is_selfhost(conn, _opts) do
|
||||
assign(conn, :is_selfhost, Plausible.Release.selfhost?())
|
||||
end
|
||||
|
||||
def register_form(conn, _params) do
|
||||
if Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_registration) != false do
|
||||
redirect(conn, to: Routes.auth_path(conn, :login_form))
|
||||
else
|
||||
changeset = Plausible.Auth.User.changeset(%Plausible.Auth.User{})
|
||||
changeset = Auth.User.changeset(%Auth.User{})
|
||||
|
||||
render(conn, "register_form.html",
|
||||
changeset: changeset,
|
||||
layout: {PlausibleWeb.LayoutView, "focus.html"}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def register(conn, params) do
|
||||
if Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_registration) != false do
|
||||
redirect(conn, to: Routes.auth_path(conn, :login_form))
|
||||
else
|
||||
conn = put_layout(conn, {PlausibleWeb.LayoutView, "focus.html"})
|
||||
user = Plausible.Auth.User.new(params["user"])
|
||||
|
||||
if PlausibleWeb.Captcha.verify(params["h-captcha-response"]) do
|
||||
@ -48,30 +66,23 @@ defmodule PlausibleWeb.AuthController do
|
||||
{:ok, user} ->
|
||||
conn = set_user_session(conn, user)
|
||||
|
||||
case user.email_verified do
|
||||
false ->
|
||||
if user.email_verified do
|
||||
redirect(conn, to: Routes.site_path(conn, :new))
|
||||
else
|
||||
send_email_verification(user)
|
||||
redirect(conn, to: Routes.auth_path(conn, :activate_form))
|
||||
|
||||
true ->
|
||||
redirect(conn, to: Routes.site_path(conn, :new))
|
||||
end
|
||||
|
||||
{:error, changeset} ->
|
||||
render(conn, "register_form.html",
|
||||
changeset: changeset,
|
||||
layout: {PlausibleWeb.LayoutView, "focus.html"}
|
||||
)
|
||||
render(conn, "register_form.html", changeset: changeset)
|
||||
end
|
||||
else
|
||||
render(conn, "register_form.html",
|
||||
changeset: user,
|
||||
captcha_error: "Please complete the captcha to register",
|
||||
layout: {PlausibleWeb.LayoutView, "focus.html"}
|
||||
captcha_error: "Please complete the captcha to register"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def register_from_invitation_form(conn, %{"invitation_id" => invitation_id}) do
|
||||
if Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_registration) == true do
|
||||
|
@ -1,14 +1,15 @@
|
||||
defmodule PlausibleWeb.PageController do
|
||||
use PlausibleWeb, :controller
|
||||
use Plausible.Repo
|
||||
plug PlausibleWeb.AutoAuthPlug
|
||||
|
||||
@doc """
|
||||
The root path is never accessible in Plausible.Cloud because it is handled by the upstream reverse proxy.
|
||||
|
||||
This controller action is only ever triggered in self-hosted Plausible. It redirects the user to /login where `PlausibleWeb.RequireLoggedOutPlug` plug kicks in. If they are already logged in, they are redirected to /sites, otherwise they'll see the /login page.
|
||||
"""
|
||||
def index(conn, _params) do
|
||||
if conn.assigns[:current_user] do
|
||||
user = conn.assigns[:current_user] |> Repo.preload(:sites)
|
||||
render(conn, "sites.html", sites: user.sites)
|
||||
else
|
||||
render(conn, "index.html")
|
||||
end
|
||||
conn
|
||||
|> put_session(:login_dest, conn.request_path)
|
||||
|> redirect(to: "/login")
|
||||
end
|
||||
end
|
||||
|
@ -1,25 +0,0 @@
|
||||
defmodule PlausibleWeb.AutoAuthPlug do
|
||||
import Plug.Conn
|
||||
alias PlausibleWeb.AuthController
|
||||
|
||||
def init(options) do
|
||||
options
|
||||
end
|
||||
|
||||
def call(conn, _opts) do
|
||||
cond do
|
||||
Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_authentication) ->
|
||||
conn
|
||||
|> AuthController.login(%{
|
||||
"email" => Application.fetch_env!(:plausible, :admin_email),
|
||||
"password" => Application.fetch_env!(:plausible, :admin_pwd)
|
||||
})
|
||||
|> halt
|
||||
|
||||
true ->
|
||||
Plug.Conn.put_session(conn, :login_dest, conn.request_path)
|
||||
|> Phoenix.Controller.redirect(to: "/login")
|
||||
|> halt
|
||||
end
|
||||
end
|
||||
end
|
26
lib/plausible_web/plugs/first_launch_plug.ex
Normal file
26
lib/plausible_web/plugs/first_launch_plug.ex
Normal file
@ -0,0 +1,26 @@
|
||||
defmodule PlausibleWeb.FirstLaunchPlug do
|
||||
@moduledoc """
|
||||
Redirects first-launch users to registration page.
|
||||
"""
|
||||
|
||||
@behaviour Plug
|
||||
alias Plausible.Release
|
||||
|
||||
@impl true
|
||||
def init(opts) do
|
||||
_path = Keyword.fetch!(opts, :redirect_to)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def call(%Plug.Conn{request_path: path} = conn, path), do: conn
|
||||
|
||||
def call(conn, redirect_to) do
|
||||
if Release.should_be_first_launch?() do
|
||||
conn
|
||||
|> Phoenix.Controller.redirect(to: redirect_to)
|
||||
|> Plug.Conn.halt()
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
end
|
@ -8,6 +8,7 @@ defmodule PlausibleWeb.Router do
|
||||
plug :fetch_session
|
||||
plug :fetch_flash
|
||||
plug :put_secure_browser_headers
|
||||
plug PlausibleWeb.FirstLaunchPlug, redirect_to: "/register"
|
||||
plug PlausibleWeb.SessionTimeoutPlug, timeout_after_seconds: @two_weeks_in_seconds
|
||||
plug PlausibleWeb.AuthPlug
|
||||
plug PlausibleWeb.LastSeenPlug
|
||||
|
@ -1,5 +1,11 @@
|
||||
<div class="mx-auto mt-6 text-center dark:text-gray-300">
|
||||
<h1 class="text-3xl font-black">Register your 30-day unlimited-use free trial</h1>
|
||||
<h1 class="text-3xl font-black">
|
||||
<%= if @is_selfhost do %>
|
||||
Register your Plausible Analytics account
|
||||
<% else %>
|
||||
Register your 30-day unlimited-use free trial
|
||||
<% end %>
|
||||
</h1>
|
||||
<div class="text-xl font-medium">Set up privacy-friendly analytics with just a few clicks</div>
|
||||
</div>
|
||||
|
||||
@ -53,7 +59,15 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= submit "Start my free trial →", class: "button mt-4 w-full" %>
|
||||
<%
|
||||
submit_text =
|
||||
if @is_selfhost do
|
||||
"Create my account →"
|
||||
else
|
||||
"Start my free trial →"
|
||||
end
|
||||
%>
|
||||
<%= submit submit_text, class: "button mt-4 w-full" %>
|
||||
|
||||
<p class="text-center text-gray-600 dark:text-gray-500 text-xs mt-4">
|
||||
Already have an account? <%= link("Log in", to: "/login", class: "underline text-gray-800 dark:text-gray-50") %> instead.
|
||||
|
@ -46,14 +46,6 @@
|
||||
<li id="changelog-notification" class="relative py-2"></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_authentication) -> %>
|
||||
<ul class="flex" x-show="!document.cookie.includes('logged_in=true')">
|
||||
<li>
|
||||
<div class="inline-flex ml-6 rounded shadow">
|
||||
<a href="/" class="inline-flex items-center justify-center px-5 py-2 text-base font-medium text-white bg-indigo-600 border border-transparent leading-6 rounded-md hover:bg-indigo-500 focus:outline-none focus:ring transition duration-150 ease-in-out">My Sites</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<% Keyword.fetch!(Application.get_env(:plausible, :selfhost), :disable_registration) != false -> %>
|
||||
<ul class="flex" x-show="!document.cookie.includes('logged_in=true')">
|
||||
<li>
|
||||
|
@ -1,3 +0,0 @@
|
||||
<div class="relative bg-gray-50 dark:bg-gray-800 overflow-hidden text-center dark:text-gray-100">
|
||||
You will be redirected... If it doesn't work, please click login.
|
||||
</div>
|
@ -2,10 +2,6 @@ defmodule PlausibleWeb.AuthView do
|
||||
use PlausibleWeb, :view
|
||||
alias Plausible.Billing.Plans
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def base_domain do
|
||||
PlausibleWeb.Endpoint.host()
|
||||
end
|
||||
|
@ -1,10 +1,6 @@
|
||||
defmodule PlausibleWeb.BillingView do
|
||||
use PlausibleWeb, :view
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def base_domain do
|
||||
PlausibleWeb.Endpoint.host()
|
||||
end
|
||||
|
@ -1,10 +1,6 @@
|
||||
defmodule PlausibleWeb.EmailView do
|
||||
use PlausibleWeb, :view
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def plausible_url do
|
||||
PlausibleWeb.Endpoint.url()
|
||||
end
|
||||
|
@ -1,10 +1,6 @@
|
||||
defmodule PlausibleWeb.LayoutView do
|
||||
use PlausibleWeb, :view
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def base_domain do
|
||||
PlausibleWeb.Endpoint.host()
|
||||
end
|
||||
|
@ -1,15 +0,0 @@
|
||||
defmodule PlausibleWeb.PageView do
|
||||
use PlausibleWeb, :view
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def base_domain do
|
||||
PlausibleWeb.Endpoint.host()
|
||||
end
|
||||
|
||||
def plausible_url do
|
||||
PlausibleWeb.Endpoint.url()
|
||||
end
|
||||
end
|
@ -2,10 +2,6 @@ defmodule PlausibleWeb.SiteView do
|
||||
use PlausibleWeb, :view
|
||||
import Phoenix.Pagination.HTML
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def plausible_url do
|
||||
PlausibleWeb.Endpoint.url()
|
||||
end
|
||||
|
@ -1,10 +1,6 @@
|
||||
defmodule PlausibleWeb.StatsView do
|
||||
use PlausibleWeb, :view
|
||||
|
||||
def admin_email do
|
||||
Application.get_env(:plausible, :admin_email)
|
||||
end
|
||||
|
||||
def base_domain do
|
||||
PlausibleWeb.Endpoint.host()
|
||||
end
|
||||
|
@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Create an admin user
|
||||
|
||||
BIN_DIR=$(dirname "$0")
|
||||
|
||||
"${BIN_DIR}"/bin/plausible eval Plausible.Release.init_admin
|
||||
echo "init-admin is deprecated and is no-op now"
|
||||
echo "user registration on first launch happens via Web UI instead"
|
||||
|
30
test/plausible/release_test.exs
Normal file
30
test/plausible/release_test.exs
Normal file
@ -0,0 +1,30 @@
|
||||
defmodule Plausible.ReleaseTest do
|
||||
use Plausible.DataCase
|
||||
alias Plausible.{Release, Auth}
|
||||
|
||||
describe "should_be_first_launch?/0" do
|
||||
test "returns true when self-hosted and no users" do
|
||||
patch_env(:is_selfhost, true)
|
||||
refute Repo.exists?(Auth.User)
|
||||
assert Release.should_be_first_launch?()
|
||||
end
|
||||
|
||||
test "returns false when not self-hosted and has no users" do
|
||||
patch_env(:is_selfhost, false)
|
||||
refute Repo.exists?(Auth.User)
|
||||
refute Release.should_be_first_launch?()
|
||||
end
|
||||
|
||||
test "returns false when not self-hosted and has users" do
|
||||
insert(:user)
|
||||
patch_env(:is_selfhost, false)
|
||||
refute Release.should_be_first_launch?()
|
||||
end
|
||||
|
||||
test "returns false when self-hosted and has users" do
|
||||
insert(:user)
|
||||
patch_env(:is_selfhost, true)
|
||||
refute Release.should_be_first_launch?()
|
||||
end
|
||||
end
|
||||
end
|
@ -1,52 +1,33 @@
|
||||
defmodule PlausibleWeb.AdminAuthControllerTest do
|
||||
use PlausibleWeb.ConnCase
|
||||
alias Plausible.Release
|
||||
|
||||
setup_patch_env(:is_selfhost, true)
|
||||
|
||||
describe "GET /" do
|
||||
test "no landing page", %{conn: conn} do
|
||||
set_config(disable_authentication: false)
|
||||
conn = get(conn, "/")
|
||||
assert redirected_to(conn) == "/login"
|
||||
end
|
||||
|
||||
test "logs admin user in automatically when authentication is disabled", %{conn: conn} do
|
||||
set_config(disable_authentication: true)
|
||||
|
||||
admin_user =
|
||||
insert(:user,
|
||||
email: Application.get_env(:plausible, :admin_email),
|
||||
password: Application.get_env(:plausible, :admin_pwd)
|
||||
)
|
||||
|
||||
# goto landing page
|
||||
conn = get(conn, "/")
|
||||
assert get_session(conn, :current_user_id) == admin_user.id
|
||||
assert redirected_to(conn) == "/sites"
|
||||
|
||||
# trying logging out
|
||||
conn = get(conn, "/logout")
|
||||
assert redirected_to(conn) == "/"
|
||||
conn = get(conn, "/")
|
||||
assert redirected_to(conn) == "/sites"
|
||||
end
|
||||
|
||||
test "disable registration", %{conn: conn} do
|
||||
set_config(disable_registration: true)
|
||||
prevent_first_launch()
|
||||
patch_config(disable_registration: true)
|
||||
conn = get(conn, "/register")
|
||||
assert redirected_to(conn) == "/login"
|
||||
end
|
||||
|
||||
test "disable registration + first launch", %{conn: conn} do
|
||||
patch_config(disable_registration: true)
|
||||
assert Release.should_be_first_launch?()
|
||||
|
||||
# "first launch" takes precedence
|
||||
conn = get(conn, "/register")
|
||||
assert html_response(conn, 200) =~ "Enter your details"
|
||||
end
|
||||
end
|
||||
|
||||
def set_config(config) do
|
||||
updated_config =
|
||||
Keyword.merge(
|
||||
[disable_authentication: false, disable_registration: false],
|
||||
config
|
||||
)
|
||||
def patch_config(config) do
|
||||
updated_config = Keyword.merge([disable_registration: false], config)
|
||||
patch_env(:selfhost, updated_config)
|
||||
end
|
||||
|
||||
Application.put_env(
|
||||
:plausible,
|
||||
:selfhost,
|
||||
updated_config
|
||||
)
|
||||
defp prevent_first_launch do
|
||||
insert(:user)
|
||||
end
|
||||
end
|
||||
|
73
test/plausible_web/plugs/first_launch_plug_test.exs
Normal file
73
test/plausible_web/plugs/first_launch_plug_test.exs
Normal file
@ -0,0 +1,73 @@
|
||||
defmodule PlausibleWeb.FirstLaunchPlugTest do
|
||||
use PlausibleWeb.ConnCase
|
||||
import Plug.Test
|
||||
|
||||
alias PlausibleWeb.FirstLaunchPlug
|
||||
alias Plausible.Release
|
||||
|
||||
describe "init/1" do
|
||||
test "requires :redirect_to option" do
|
||||
assert_raise KeyError, ~r"key :redirect_to not found", fn ->
|
||||
FirstLaunchPlug.init(_no_opts = [])
|
||||
end
|
||||
|
||||
path = FirstLaunchPlug.init(redirect_to: "/register")
|
||||
assert path == "/register"
|
||||
end
|
||||
end
|
||||
|
||||
@opts FirstLaunchPlug.init(redirect_to: "/register")
|
||||
|
||||
describe "call/2" do
|
||||
test "no-op for paths == :redirect_to" do
|
||||
conn = conn("GET", "/register")
|
||||
conn = FirstLaunchPlug.call(conn, @opts)
|
||||
refute conn.halted
|
||||
|
||||
# even when it's the first launch
|
||||
patch_env(:is_selfhost, true)
|
||||
assert Release.should_be_first_launch?()
|
||||
|
||||
conn = conn("GET", "/register")
|
||||
conn = FirstLaunchPlug.call(conn, @opts)
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
test "no-op when not first launch" do
|
||||
refute Release.should_be_first_launch?()
|
||||
conn = conn("GET", "/sites")
|
||||
conn = FirstLaunchPlug.call(conn, @opts)
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
test "redirects to :redirect_to when first launch" do
|
||||
patch_env(:is_selfhost, true)
|
||||
assert Release.should_be_first_launch?()
|
||||
|
||||
conn = conn("GET", "/sites")
|
||||
conn = FirstLaunchPlug.call(conn, @opts)
|
||||
assert conn.halted
|
||||
assert redirected_to(conn) == "/register"
|
||||
end
|
||||
end
|
||||
|
||||
describe "first launch plug in :browser pipeline" do
|
||||
test "redirects to /register on first launch", %{conn: conn} do
|
||||
patch_env(:is_selfhost, true)
|
||||
assert Release.should_be_first_launch?()
|
||||
|
||||
conn = get(conn, "/")
|
||||
assert redirected_to(conn) == "/register"
|
||||
end
|
||||
|
||||
test "no-op when not first launch", %{conn: conn} do
|
||||
patch_env(:is_selfhost, false)
|
||||
refute Release.should_be_first_launch?()
|
||||
|
||||
# gets redirected to login by auth plugs
|
||||
# "first launch" doesn't interfere
|
||||
conn = get(conn, "/sites")
|
||||
assert redirected_to(conn) == "/login"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user