diff --git a/authentik/brands/api.py b/authentik/brands/api.py
index 3089f86eab..bcfd0fc6db 100644
--- a/authentik/brands/api.py
+++ b/authentik/brands/api.py
@@ -50,6 +50,7 @@ class BrandSerializer(ModelSerializer):
"branding_logo",
"branding_favicon",
"branding_custom_css",
+ "branding_default_flow_background",
"flow_authentication",
"flow_invalidation",
"flow_recovery",
@@ -127,6 +128,7 @@ class BrandViewSet(UsedByMixin, ModelViewSet):
"branding_title",
"branding_logo",
"branding_favicon",
+ "branding_default_flow_background",
"flow_authentication",
"flow_invalidation",
"flow_recovery",
diff --git a/authentik/brands/migrations/0009_brand_branding_default_flow_background.py b/authentik/brands/migrations/0009_brand_branding_default_flow_background.py
new file mode 100644
index 0000000000..9c295e5154
--- /dev/null
+++ b/authentik/brands/migrations/0009_brand_branding_default_flow_background.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.13 on 2025-03-19 22:54
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("authentik_brands", "0008_brand_branding_custom_css"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="brand",
+ name="branding_default_flow_background",
+ field=models.TextField(default="/static/dist/assets/images/flow_background.jpg"),
+ ),
+ ]
diff --git a/authentik/brands/models.py b/authentik/brands/models.py
index ee4e73d52b..cc8cc43787 100644
--- a/authentik/brands/models.py
+++ b/authentik/brands/models.py
@@ -34,6 +34,9 @@ class Brand(SerializerModel):
branding_logo = models.TextField(default="/static/dist/assets/icons/icon_left_brand.svg")
branding_favicon = models.TextField(default="/static/dist/assets/icons/icon.png")
branding_custom_css = models.TextField(default="", blank=True)
+ branding_default_flow_background = models.TextField(
+ default="/static/dist/assets/images/flow_background.jpg"
+ )
flow_authentication = models.ForeignKey(
Flow, null=True, on_delete=models.SET_NULL, related_name="brand_authentication"
@@ -85,6 +88,12 @@ class Brand(SerializerModel):
return CONFIG.get("web.path", "/")[:-1] + self.branding_favicon
return self.branding_favicon
+ def branding_default_flow_background_url(self) -> str:
+ """Get branding_default_flow_background with the correct prefix"""
+ if self.branding_default_flow_background.startswith("/static"):
+ return CONFIG.get("web.path", "/")[:-1] + self.branding_default_flow_background
+ return self.branding_default_flow_background
+
@property
def serializer(self) -> Serializer:
from authentik.brands.api import BrandSerializer
diff --git a/authentik/brands/tests.py b/authentik/brands/tests.py
index f03dea322e..e320340565 100644
--- a/authentik/brands/tests.py
+++ b/authentik/brands/tests.py
@@ -124,3 +124,27 @@ class TestBrands(APITestCase):
"subject": None,
},
)
+
+ def test_branding_url(self):
+ """Test branding attributes return correct values"""
+ brand = create_test_brand()
+ brand.branding_default_flow_background = "https://goauthentik.io/img/icon.png"
+ brand.branding_favicon = "https://goauthentik.io/img/icon.png"
+ brand.branding_logo = "https://goauthentik.io/img/icon.png"
+ brand.save()
+ self.assertEqual(
+ brand.branding_default_flow_background_url(), "https://goauthentik.io/img/icon.png"
+ )
+ self.assertJSONEqual(
+ self.client.get(reverse("authentik_api:brand-current")).content.decode(),
+ {
+ "branding_logo": "https://goauthentik.io/img/icon.png",
+ "branding_favicon": "https://goauthentik.io/img/icon.png",
+ "branding_title": "authentik",
+ "branding_custom_css": "",
+ "matched_domain": brand.domain,
+ "ui_footer_links": [],
+ "ui_theme": Themes.AUTOMATIC,
+ "default_locale": "",
+ },
+ )
diff --git a/authentik/core/templates/login/base_full.html b/authentik/core/templates/login/base_full.html
index cbab6c2ed5..f312a4e7a0 100644
--- a/authentik/core/templates/login/base_full.html
+++ b/authentik/core/templates/login/base_full.html
@@ -4,7 +4,7 @@
{% load i18n %}
{% block head_before %}
-
+
{% include "base/header_js.html" %}
@@ -13,7 +13,7 @@
{% block head %}