brands: migrate custom CSS to brands (#13172)
* brands: migrate custom CSS to brands Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix missing default Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * simpler migration Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add css to brand form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -49,6 +49,7 @@ class BrandSerializer(ModelSerializer):
|
|||||||
"branding_title",
|
"branding_title",
|
||||||
"branding_logo",
|
"branding_logo",
|
||||||
"branding_favicon",
|
"branding_favicon",
|
||||||
|
"branding_custom_css",
|
||||||
"flow_authentication",
|
"flow_authentication",
|
||||||
"flow_invalidation",
|
"flow_invalidation",
|
||||||
"flow_recovery",
|
"flow_recovery",
|
||||||
@ -86,6 +87,7 @@ class CurrentBrandSerializer(PassiveSerializer):
|
|||||||
branding_title = CharField()
|
branding_title = CharField()
|
||||||
branding_logo = CharField(source="branding_logo_url")
|
branding_logo = CharField(source="branding_logo_url")
|
||||||
branding_favicon = CharField(source="branding_favicon_url")
|
branding_favicon = CharField(source="branding_favicon_url")
|
||||||
|
branding_custom_css = CharField()
|
||||||
ui_footer_links = ListField(
|
ui_footer_links = ListField(
|
||||||
child=FooterLinkSerializer(),
|
child=FooterLinkSerializer(),
|
||||||
read_only=True,
|
read_only=True,
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
# Generated by Django 5.0.12 on 2025-02-22 01:51
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from django.db import migrations, models
|
||||||
|
from django.apps.registry import Apps
|
||||||
|
|
||||||
|
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_custom_css(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||||
|
Brand = apps.get_model("authentik_brands", "brand")
|
||||||
|
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
|
||||||
|
path = Path("/web/dist/custom.css")
|
||||||
|
if not path.exists():
|
||||||
|
return
|
||||||
|
with path.read_text() as css:
|
||||||
|
Brand.objects.using(db_alias).update(branding_custom_css=css)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_brands", "0007_brand_default_application"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="brand",
|
||||||
|
name="branding_custom_css",
|
||||||
|
field=models.TextField(blank=True, default=""),
|
||||||
|
),
|
||||||
|
migrations.RunPython(migrate_custom_css),
|
||||||
|
]
|
@ -33,6 +33,7 @@ class Brand(SerializerModel):
|
|||||||
|
|
||||||
branding_logo = models.TextField(default="/static/dist/assets/icons/icon_left_brand.svg")
|
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_favicon = models.TextField(default="/static/dist/assets/icons/icon.png")
|
||||||
|
branding_custom_css = models.TextField(default="", blank=True)
|
||||||
|
|
||||||
flow_authentication = models.ForeignKey(
|
flow_authentication = models.ForeignKey(
|
||||||
Flow, null=True, on_delete=models.SET_NULL, related_name="brand_authentication"
|
Flow, null=True, on_delete=models.SET_NULL, related_name="brand_authentication"
|
||||||
|
@ -24,6 +24,7 @@ class TestBrands(APITestCase):
|
|||||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||||
"branding_title": "authentik",
|
"branding_title": "authentik",
|
||||||
|
"branding_custom_css": "",
|
||||||
"matched_domain": brand.domain,
|
"matched_domain": brand.domain,
|
||||||
"ui_footer_links": [],
|
"ui_footer_links": [],
|
||||||
"ui_theme": Themes.AUTOMATIC,
|
"ui_theme": Themes.AUTOMATIC,
|
||||||
@ -43,6 +44,7 @@ class TestBrands(APITestCase):
|
|||||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||||
"branding_title": "custom",
|
"branding_title": "custom",
|
||||||
|
"branding_custom_css": "",
|
||||||
"matched_domain": "bar.baz",
|
"matched_domain": "bar.baz",
|
||||||
"ui_footer_links": [],
|
"ui_footer_links": [],
|
||||||
"ui_theme": Themes.AUTOMATIC,
|
"ui_theme": Themes.AUTOMATIC,
|
||||||
@ -59,6 +61,7 @@ class TestBrands(APITestCase):
|
|||||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||||
"branding_title": "authentik",
|
"branding_title": "authentik",
|
||||||
|
"branding_custom_css": "",
|
||||||
"matched_domain": "fallback",
|
"matched_domain": "fallback",
|
||||||
"ui_footer_links": [],
|
"ui_footer_links": [],
|
||||||
"ui_theme": Themes.AUTOMATIC,
|
"ui_theme": Themes.AUTOMATIC,
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
{% block head_before %}
|
{% block head_before %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
|
<style>{{ brand.branding_custom_css }}</style>
|
||||||
<script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
|
||||||
<script src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}" type="module"></script>
|
<script src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}" type="module"></script>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
|
@ -13016,6 +13016,10 @@
|
|||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
"title": "Branding favicon"
|
"title": "Branding favicon"
|
||||||
},
|
},
|
||||||
|
"branding_custom_css": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Branding custom css"
|
||||||
|
},
|
||||||
"flow_authentication": {
|
"flow_authentication": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "uuid",
|
"format": "uuid",
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
<link rel="shortcut icon" type="image/png" href="/outpost.goauthentik.io/static/dist/assets/icons/icon.png">
|
<link rel="shortcut icon" type="image/png" href="/outpost.goauthentik.io/static/dist/assets/icons/icon.png">
|
||||||
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/patternfly.min.css">
|
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/patternfly.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/authentik.css">
|
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/authentik.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/outpost.goauthentik.io/static/dist/custom.css">
|
|
||||||
<link rel="prefetch" href="/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg" />
|
<link rel="prefetch" href="/outpost.goauthentik.io/static/dist/assets/images/flow_background.jpg" />
|
||||||
<style>
|
<style>
|
||||||
.pf-c-background-image::before {
|
.pf-c-background-image::before {
|
||||||
|
@ -41145,6 +41145,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
branding_favicon:
|
branding_favicon:
|
||||||
type: string
|
type: string
|
||||||
|
branding_custom_css:
|
||||||
|
type: string
|
||||||
flow_authentication:
|
flow_authentication:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
@ -41204,6 +41206,8 @@ components:
|
|||||||
branding_favicon:
|
branding_favicon:
|
||||||
type: string
|
type: string
|
||||||
minLength: 1
|
minLength: 1
|
||||||
|
branding_custom_css:
|
||||||
|
type: string
|
||||||
flow_authentication:
|
flow_authentication:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
@ -42096,6 +42100,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
branding_favicon:
|
branding_favicon:
|
||||||
type: string
|
type: string
|
||||||
|
branding_custom_css:
|
||||||
|
type: string
|
||||||
ui_footer_links:
|
ui_footer_links:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -42122,6 +42128,7 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
required:
|
required:
|
||||||
|
- branding_custom_css
|
||||||
- branding_favicon
|
- branding_favicon
|
||||||
- branding_logo
|
- branding_logo
|
||||||
- branding_title
|
- branding_title
|
||||||
@ -50125,6 +50132,8 @@ components:
|
|||||||
branding_favicon:
|
branding_favicon:
|
||||||
type: string
|
type: string
|
||||||
minLength: 1
|
minLength: 1
|
||||||
|
branding_custom_css:
|
||||||
|
type: string
|
||||||
flow_authentication:
|
flow_authentication:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
8
web/package-lock.json
generated
8
web/package-lock.json
generated
@ -14,6 +14,7 @@
|
|||||||
"./packages/*"
|
"./packages/*"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@codemirror/lang-css": "^6.3.1",
|
||||||
"@codemirror/lang-html": "^6.4.9",
|
"@codemirror/lang-html": "^6.4.9",
|
||||||
"@codemirror/lang-javascript": "^6.2.2",
|
"@codemirror/lang-javascript": "^6.2.2",
|
||||||
"@codemirror/lang-python": "^6.1.6",
|
"@codemirror/lang-python": "^6.1.6",
|
||||||
@ -1039,9 +1040,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/lang-css": {
|
"node_modules/@codemirror/lang-css": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz",
|
||||||
"integrity": "sha512-CyR4rUNG9OYcXDZwMPvJdtb6PHbBDKUc/6Na2BIwZ6dKab1JQqKa4di+RNRY9Myn7JB81vayKwJeQ7jEdmNVDA==",
|
"integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "@goauthentik/web",
|
"name": "@goauthentik/web",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@codemirror/lang-css": "^6.3.1",
|
||||||
"@codemirror/lang-html": "^6.4.9",
|
"@codemirror/lang-html": "^6.4.9",
|
||||||
"@codemirror/lang-javascript": "^6.2.2",
|
"@codemirror/lang-javascript": "^6.2.2",
|
||||||
"@codemirror/lang-python": "^6.1.6",
|
"@codemirror/lang-python": "^6.1.6",
|
||||||
@ -182,7 +183,6 @@
|
|||||||
"./dist/enterprise/**",
|
"./dist/enterprise/**",
|
||||||
"./dist/poly-*.js",
|
"./dist/poly-*.js",
|
||||||
"./dist/poly-*.js.map",
|
"./dist/poly-*.js.map",
|
||||||
"./dist/custom.css",
|
|
||||||
"./dist/theme-dark.css",
|
"./dist/theme-dark.css",
|
||||||
"./dist/one-dark.css",
|
"./dist/one-dark.css",
|
||||||
"./dist/patternfly.min.css"
|
"./dist/patternfly.min.css"
|
||||||
|
@ -52,7 +52,6 @@ const definitions = Object.fromEntries(
|
|||||||
const assetsFileMappings = [
|
const assetsFileMappings = [
|
||||||
["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
|
["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
|
||||||
["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
|
["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
|
||||||
["src/custom.css", "."],
|
|
||||||
["src/common/styles/**", "."],
|
["src/common/styles/**", "."],
|
||||||
["src/assets/images/**", "./assets/images"],
|
["src/assets/images/**", "./assets/images"],
|
||||||
["./icons/*", "./assets/icons"],
|
["./icons/*", "./assets/icons"],
|
||||||
|
@ -51,11 +51,7 @@ export class BrandForm extends ModelForm<Brand, string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderForm(): TemplateResult {
|
renderForm(): TemplateResult {
|
||||||
return html` <ak-form-element-horizontal
|
return html` <ak-form-element-horizontal label=${msg("Domain")} required name="domain">
|
||||||
label=${msg("Domain")}
|
|
||||||
?required=${true}
|
|
||||||
name="domain"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value="${first(this.instance?.domain, window.location.host)}"
|
value="${first(this.instance?.domain, window.location.host)}"
|
||||||
@ -90,14 +86,10 @@ export class BrandForm extends ModelForm<Brand, string> {
|
|||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
|
|
||||||
<ak-form-group .expanded=${true}>
|
<ak-form-group>
|
||||||
<span slot="header"> ${msg("Branding settings")} </span>
|
<span slot="header"> ${msg("Branding settings")} </span>
|
||||||
<div slot="body" class="pf-c-form">
|
<div slot="body" class="pf-c-form">
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal label=${msg("Title")} required name="brandingTitle">
|
||||||
label=${msg("Title")}
|
|
||||||
?required=${true}
|
|
||||||
name="brandingTitle"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value="${first(
|
value="${first(
|
||||||
@ -111,11 +103,7 @@ export class BrandForm extends ModelForm<Brand, string> {
|
|||||||
${msg("Branding shown in page title and several other places.")}
|
${msg("Branding shown in page title and several other places.")}
|
||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal label=${msg("Logo")} required name="brandingLogo">
|
||||||
label=${msg("Logo")}
|
|
||||||
?required=${true}
|
|
||||||
name="brandingLogo"
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value="${first(this.instance?.brandingLogo, DefaultBrand.brandingLogo)}"
|
value="${first(this.instance?.brandingLogo, DefaultBrand.brandingLogo)}"
|
||||||
@ -130,7 +118,7 @@ export class BrandForm extends ModelForm<Brand, string> {
|
|||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal
|
||||||
label=${msg("Favicon")}
|
label=${msg("Favicon")}
|
||||||
?required=${true}
|
required
|
||||||
name="brandingFavicon"
|
name="brandingFavicon"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@ -148,6 +136,23 @@ export class BrandForm extends ModelForm<Brand, string> {
|
|||||||
${msg("Icon shown in the browser tab.")}
|
${msg("Icon shown in the browser tab.")}
|
||||||
</p>
|
</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${msg("Custom CSS")}
|
||||||
|
required
|
||||||
|
name="brandingCustomCss"
|
||||||
|
>
|
||||||
|
<ak-codemirror
|
||||||
|
mode=${CodeMirrorMode.CSS}
|
||||||
|
value="${first(
|
||||||
|
this.instance?.brandingCustomCss,
|
||||||
|
DefaultBrand.brandingCustomCss,
|
||||||
|
)}"
|
||||||
|
>
|
||||||
|
</ak-codemirror>
|
||||||
|
<p class="pf-c-form__helper-text">
|
||||||
|
${msg("Custom CSS to apply to pages when this brand is active.")}
|
||||||
|
</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
</div>
|
</div>
|
||||||
</ak-form-group>
|
</ak-form-group>
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
/* User customisable */
|
|
@ -24,26 +24,6 @@ type AkInterface = HTMLElement & {
|
|||||||
export const rootInterface = <T extends AkInterface>(): T | undefined =>
|
export const rootInterface = <T extends AkInterface>(): T | undefined =>
|
||||||
(document.body.querySelector("[data-ak-interface-root]") as T) ?? undefined;
|
(document.body.querySelector("[data-ak-interface-root]") as T) ?? undefined;
|
||||||
|
|
||||||
let css: Promise<string[]> | undefined;
|
|
||||||
function fetchCustomCSS(): Promise<string[]> {
|
|
||||||
if (!css) {
|
|
||||||
css = Promise.all(
|
|
||||||
Array.of(...document.head.querySelectorAll<HTMLLinkElement>("link[data-inject]")).map(
|
|
||||||
(link) => {
|
|
||||||
return fetch(link.href)
|
|
||||||
.then((res) => {
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return css;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const QUERY_MEDIA_COLOR_LIGHT = "(prefers-color-scheme: light)";
|
export const QUERY_MEDIA_COLOR_LIGHT = "(prefers-color-scheme: light)";
|
||||||
|
|
||||||
// Ensure themes are converted to a static instance of CSS Stylesheet, otherwise the
|
// Ensure themes are converted to a static instance of CSS Stylesheet, otherwise the
|
||||||
@ -103,15 +83,12 @@ export class AKElement extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _initCustomCSS(root: DocumentOrShadowRoot): Promise<void> {
|
async _initCustomCSS(root: DocumentOrShadowRoot): Promise<void> {
|
||||||
const sheets = await fetchCustomCSS();
|
const brand = globalAK().brand;
|
||||||
sheets.map((css) => {
|
if (!brand) {
|
||||||
if (css === "") {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
const sheet = await new CSSStyleSheet().replace(brand.brandingCustomCss);
|
||||||
new CSSStyleSheet().replace(css).then((sheet) => {
|
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];
|
||||||
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyTheme(root: DocumentOrShadowRoot, theme?: UiThemeEnum): void {
|
_applyTheme(root: DocumentOrShadowRoot, theme?: UiThemeEnum): void {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
||||||
|
import { css as cssLang } from "@codemirror/lang-css";
|
||||||
import { html as htmlLang } from "@codemirror/lang-html";
|
import { html as htmlLang } from "@codemirror/lang-html";
|
||||||
import { javascript } from "@codemirror/lang-javascript";
|
import { javascript } from "@codemirror/lang-javascript";
|
||||||
import { python } from "@codemirror/lang-python";
|
import { python } from "@codemirror/lang-python";
|
||||||
@ -27,6 +28,7 @@ export enum CodeMirrorMode {
|
|||||||
XML = "xml",
|
XML = "xml",
|
||||||
JavaScript = "javascript",
|
JavaScript = "javascript",
|
||||||
HTML = "html",
|
HTML = "html",
|
||||||
|
CSS = "css",
|
||||||
Python = "python",
|
Python = "python",
|
||||||
YAML = "yaml",
|
YAML = "yaml",
|
||||||
}
|
}
|
||||||
@ -147,6 +149,8 @@ export class CodeMirrorTextarea<T> extends AKElement {
|
|||||||
return htmlLang();
|
return htmlLang();
|
||||||
case CodeMirrorMode.Python:
|
case CodeMirrorMode.Python:
|
||||||
return python();
|
return python();
|
||||||
|
case CodeMirrorMode.CSS:
|
||||||
|
return cssLang();
|
||||||
case CodeMirrorMode.YAML:
|
case CodeMirrorMode.YAML:
|
||||||
return new LanguageSupport(StreamLanguage.define(yamlMode.yaml));
|
return new LanguageSupport(StreamLanguage.define(yamlMode.yaml));
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ export const DefaultBrand: CurrentBrand = {
|
|||||||
brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg",
|
brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg",
|
||||||
brandingFavicon: "/static/dist/assets/icons/icon.png",
|
brandingFavicon: "/static/dist/assets/icons/icon.png",
|
||||||
brandingTitle: "authentik",
|
brandingTitle: "authentik",
|
||||||
|
brandingCustomCss: "",
|
||||||
uiFooterLinks: [],
|
uiFooterLinks: [],
|
||||||
uiTheme: UiThemeEnum.Automatic,
|
uiTheme: UiThemeEnum.Automatic,
|
||||||
matchedDomain: "",
|
matchedDomain: "",
|
||||||
|
Reference in New Issue
Block a user