Branding stuff (#3816)

* Replace footer text

* add COPYING.txt file

* Add new logos

* Use new logos in all layouts

* New logos

* Check license key on startup

* Bypass license check when Mix.env == :dev

* Use new logos with smaller wordmarks

* Add generic logo_path/1 function

* Use new favicons everywhere

* Bypass license check in test env

* Use sha256 for license key hash

* Mix.env -> config_env()

* Use Mix.evn at compile time rather than runtime

* Mix format

---------

Co-authored-by: Uku Taht <uku.taht@gmail.com>
This commit is contained in:
Cenk Kücük 2024-02-23 11:35:22 +00:00 committed by GitHub
parent bdaf80c05d
commit 0f0f604d2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 179 additions and 77 deletions

View File

@ -0,0 +1,5 @@
Plausible copyright notice
This software is Copyright 2024 Plausible Insights OÜ
This repository is provided for informational purposes only, and no rights to use, distribute or otherwise exploit this software are granted to you. Our other repositories include software that is offered under the Affero GPL, but this repository is not. If you wish to discuss a license, or our hosted service that uses the software, please contact us at hello@plausible.io

View File

@ -291,13 +291,16 @@ secure_cookie =
|> get_var_from_path_or_env("SECURE_COOKIE", if(is_selfhost, do: "false", else: "true"))
|> String.to_existing_atom()
license_key = get_var_from_path_or_env(config_dir, "LICENSE_KEY", "")
config :plausible,
environment: env,
mailer_email: mailer_email,
super_admin_user_ids: super_admin_user_ids,
is_selfhost: is_selfhost,
custom_script_name: custom_script_name,
log_failed_login_attempts: log_failed_login_attempts
log_failed_login_attempts: log_failed_login_attempts,
license_key: license_key
config :plausible, :selfhost,
enable_email_verification: enable_email_verification,

5
extra/COPYING.txt Normal file
View File

@ -0,0 +1,5 @@
Plausible copyright notice
This software is Copyright 2024 Plausible Insights OÜ
This repository is provided for informational purposes only, and no rights to use, distribute or otherwise exploit this software are granted to you. Our other repositories include software that is offered under the Affero GPL, but this repository is not. If you wish to discuss a license, or our hosted service that uses the software, please contact us at hello@plausible.io

42
extra/lib/license.ex Normal file
View File

@ -0,0 +1,42 @@
defmodule Plausible.License do
@moduledoc """
This module ensures that you cannot run Plausible Analytics Enterprise Edition without a valid license key.
The software contained within the ee/ and assets/js/dashboard/ee directories are Copyright © Plausible Insights .
We have made this code available solely for informational and transparency purposes. No rights are granted to use,
distribute, or exploit this software in any form.
Any attempt to disable or modify the behavior of this module will be considered a violation of copyright.
If you wish to use the Plausible Analytics Enterprise Edition for your own requirements, please contact us
at hello@plausible.io to discuss obtaining a license.
"""
require Logger
if Mix.env() == :prod do
def ensure_valid_license do
if has_valid_license?() do
:ok
else
Logger.error(
"Invalid or no license key provided for Plausible Enterprise Edition. Please contact hello@plausible.io to acquire a license."
)
Logger.error("Shutting down")
System.stop()
end
end
@license_hash "4qidue2klxynf4vrprlxuouwjos7dnyn4nsquamkrfhtn3ts6ova===="
defp has_valid_license?() do
hash =
:crypto.hash(:sha256, Application.fetch_env!(:plausible, :license_key))
|> Base.encode32(case: :lower)
hash == @license_hash
end
else
def ensure_valid_license do
:ok
end
end
end

View File

@ -2,10 +2,13 @@ defmodule Plausible.Application do
@moduledoc false
use Application
use Plausible
require Logger
def start(_type, _args) do
on_full_build(do: Plausible.License.ensure_valid_license())
children = [
Plausible.Repo,
Plausible.ClickhouseRepo,

View File

@ -3,6 +3,28 @@ defmodule PlausibleWeb.Components.Layout do
use Phoenix.Component
def favicon(assigns) do
~H"""
<link
rel="apple-touch-icon"
sizes="180x180"
href={PlausibleWeb.Router.Helpers.static_path(@conn, logo_path("apple-touch-icon.png"))}
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href={PlausibleWeb.Router.Helpers.static_path(@conn, logo_path("favicon-32x32.png"))}
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href={PlausibleWeb.Router.Helpers.static_path(@conn, logo_path("favicon-16x16.png"))}
/>
"""
end
def theme_script(assigns) do
~H"""
<script blocking="rendering">
@ -39,4 +61,6 @@ defmodule PlausibleWeb.Components.Layout do
end
defp theme_preference(_assigns), do: "system"
defdelegate logo_path(path), to: PlausibleWeb.LayoutView
end

View File

@ -3,40 +3,29 @@
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
<div class="my-8 xl:my-0">
<h4 class="font-semibold tracking-wider text-gray-300 leading-5">
<img src="/images/icon/plausible_logo_sm.png" class="inline-block w-6 mr-1" />
Plausible Analytics
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_dark.svg")
),
class: "inline-block w-40 mr-1",
alt: "Plausible logo",
loading: "lazy"
) %>
</h4>
<p class="mt-4 text-base text-gray-400 leading-6">
<%= if full_build?() do %>
Made and hosted in the EU <span class="text-lg">🇪🇺</span> <br />
Solely funded by our subscribers.
<% end %>
Solely funded by our subscribers.<br />
</p>
<%= if small_build?() do %>
<div class="mt-4">
<a
href="https://github.com/sponsors/plausible"
class="inline-flex items-center px-4 py-2 text-sm font-medium bg-gray-700 border border-transparent shadow-sm rounded-md text-gray-50 hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500"
>
<svg
class="w-5 h-5 mr-2 -ml-1 text-pink-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
>
</path>
</svg>
Sponsor @plausible
</a>
</div>
This dashboard is running on self-managed infrastructure, not tested by Plausible Analytics. We cannot vouch for its performance or reliability. For official managed hosting, check out
<.styled_link href="https://plausible.io">
plausible.io
</.styled_link>
<% end %>
</p>
</div>
<div class="grid grid-cols-2 gap-8 xl:col-span-2">
<div class="md:grid md:grid-cols-2 md:gap-8 print:hidden">

View File

@ -6,15 +6,18 @@
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(
@conn,
"/images/icon/plausible_logo_dark.png"
logo_path("logo_dark.svg")
),
class: "h-8 w-auto sm:h-10 -mt-2 hidden dark:inline",
class: "w-44 -mt-2 hidden dark:inline",
alt: "Plausible logo",
loading: "lazy"
) %>
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_logo.png"),
class: "h-8 w-auto sm:h-10 -mt-2 inline dark:hidden",
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_light.svg")
),
class: "w-44 -mt-2 inline dark:hidden",
alt: "Plausible logo",
loading: "lazy"
) %>

View File

@ -13,13 +13,9 @@
<meta name="websocket-url" content={websocket_url()} />
<% end %>
<meta name="robots" content={@conn.private.robots} />
<link
rel="icon"
type="image/png"
sizes="32x32"
href={PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_favicon.png")}
/>
<link rel="apple-touch-icon" href="/images/icon/apple-touch-icon.png" />
<PlausibleWeb.Components.Layout.favicon conn={@conn} />
<title>
<%= assigns[:title] ||
"Plausible · Simple, privacy-friendly alternative to Google Analytics" %>

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="icon" type="image/png" sizes="32x32" href="<%= PlausibleWeb.Router.Helpers.static_path(PlausibleWeb.Endpoint, "/images/icon/plausible_favicon.png") %>">
<title>Plausible · Web analytics</title>
<link rel="stylesheet" href="<%= Routes.static_path(PlausibleWeb.Endpoint, "/css/app.css") %>"/>
</head>
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
<div class="w-full my-8 text-center">
<%= img_tag(PlausibleWeb.Router.Helpers.static_path(PlausibleWeb.Endpoint, "/images/icon/plausible_logo_dark.png"), class: "hidden dark:inline", style: "height: 2.5rem;", alt: "Plausible logo") %>
<%= img_tag(PlausibleWeb.Router.Helpers.static_path(PlausibleWeb.Endpoint, "/images/icon/plausible_logo.png"), class: "inline dark:hidden", style: "height: 2.5rem;", alt: "Plausible logo")%>
</div>
<%= @inner_content %>
<script type="text/javascript" src="<%= Routes.static_path(PlausibleWeb.Endpoint, "/js/app.js") %>"></script>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<PlausibleWeb.Components.Layout.favicon conn={@conn} />
<title>Plausible · Web analytics</title>
<link rel="stylesheet" href={Routes.static_path(PlausibleWeb.Endpoint, "/css/app.css")} />
</head>
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
<div class="w-full my-8 text-center">
<a href={home_dest(@conn)}>
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_dark.svg")
),
class: "w-44 hidden dark:inline",
alt: "Plausible logo",
loading: "lazy"
) %>
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_light.svg")
),
class: "w-44 inline dark:hidden",
alt: "Plausible logo",
loading: "lazy"
) %>
</a>
</div>
<%= @inner_content %>
<script type="text/javascript" src={Routes.static_path(PlausibleWeb.Endpoint, "/js/app.js")}>
</script>
</body>
</html>

View File

@ -13,30 +13,31 @@
<meta name="csrf-token" content={Plug.CSRFProtection.get_csrf_token()} />
<meta name="websocket-url" content={websocket_url()} />
<% end %>
<link
rel="icon"
type="image/png"
sizes="32x32"
href={PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_favicon.png")}
/>
<PlausibleWeb.Components.Layout.favicon conn={@conn} />
<title><%= assigns[:title] || "Plausible · Web analytics" %></title>
<link rel="stylesheet" href={Routes.static_path(@conn, "/css/app.css")} />
<%= render("_tracking.html", assigns) %>
</head>
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
<div class="w-full my-8 text-center">
<div class="w-full mt-12 text-center">
<a href={home_dest(@conn)}>
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_logo_dark.png"),
class: "hidden dark:inline",
style: "height: 2.5rem;",
alt: "Plausible logo"
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_dark.svg")
),
class: "w-44 hidden dark:inline",
alt: "Plausible logo",
loading: "lazy"
) %>
<%= img_tag(
PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_logo.png"),
class: "inline dark:hidden",
style: "height: 2.5rem;",
alt: "Plausible logo"
PlausibleWeb.Router.Helpers.static_path(
@conn,
logo_path("logo_light.svg")
),
class: "w-44 inline dark:hidden",
alt: "Plausible logo",
loading: "lazy"
) %>
</a>
</div>

View File

@ -40,6 +40,14 @@ defmodule PlausibleWeb.LayoutView do
end
end
def logo_path(filename) do
if full_build?() do
Path.join("/images/ee/", filename)
else
Path.join("/images/ce/", filename)
end
end
def settings_tabs(conn) do
[
[key: "General", value: "general", icon: :rocket_launch],

View File

@ -158,7 +158,7 @@ defmodule Plausible.MixProject do
defp docs do
[
main: "readme",
logo: "priv/static/images/icon/plausible_favicon.png",
logo: "priv/static/images/ee/favicon-32x32.png",
extras:
Path.wildcard("guides/**/*.md") ++
[

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB