web: Font fixes (#15581)

* add base element

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web: Rewrite relative CSS asset paths. Update fonts.

Update web/bundler/css-assets-plugin/node.js

Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Teffen Ellis
2025-07-24 17:40:38 +02:00
committed by GitHub
parent 068bd34392
commit f00772faf1
9 changed files with 90 additions and 44 deletions
+1 -1
View File
@@ -43,6 +43,6 @@ def context_processor(request: HttpRequest) -> dict[str, Any]:
"brand": brand,
"brand_css": brand_css,
"footer_links": tenant.footer_links,
"html_meta": {**get_http_meta()},
"html_meta": get_http_meta(),
"version": get_full_version(),
}
@@ -10,6 +10,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
{# Darkreader breaks the site regardless of theme as its not compatible with webcomponents, and we default to a dark theme based on preferred colour-scheme #}
<meta name="darkreader-lock">
<base href="{{ base_url_rel }}" />
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
<link rel="icon" href="{{ brand.branding_favicon_url }}">
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
-23
View File
@@ -1,11 +1,9 @@
package web
import (
"fmt"
"net/http"
"github.com/go-http-utils/etag"
"github.com/gorilla/mux"
"goauthentik.io/internal/config"
"goauthentik.io/internal/constants"
@@ -42,27 +40,6 @@ func (ws *WebServer) configureStatic() {
config.Get().Web.Path,
))
indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/if/flow/{flow_slug}/assets").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
pathStripper(
distFs,
"if/flow/"+vars["flow_slug"],
config.Get().Web.Path,
).ServeHTTP(rw, r)
})
indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/if/admin/assets").Handler(http.StripPrefix(fmt.Sprintf("%sif/admin", config.Get().Web.Path), distFs))
indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/if/user/assets").Handler(http.StripPrefix(fmt.Sprintf("%sif/user", config.Get().Web.Path), distFs))
indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/if/rac/{app_slug}/assets").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
pathStripper(
distFs,
"if/rac/"+vars["app_slug"],
config.Get().Web.Path,
).ServeHTTP(rw, r)
})
// Media files, if backend is file
if config.Get().Storage.Media.Backend == "file" {
fsMedia := http.FileServer(http.Dir(config.Get().Storage.Media.File.Path))
+30
View File
@@ -0,0 +1,30 @@
/**
* @file CSS asset rewrite plugin for ESBuild.
*
* @import { Plugin } from "esbuild"
*/
import * as fs from "node:fs/promises";
/**
* Rewrite `url()` calls in CSS files to point to the static directory.
*
* @returns {Plugin}
*/
export function cssAssetPlugin() {
return {
name: "css-text-loader",
setup: (build) => {
const URLPattern = /url\(\s*['"]?(?:[./]*)(assets\/[^)'"']*)['"]?\s*\)/g;
build.onLoad({ filter: /\.css$/ }, async (args) => {
const contents = await fs.readFile(args.path, "utf8");
return {
loader: "text",
contents: contents.replaceAll(URLPattern, "url(./static/dist/$1)"),
};
});
},
};
}
+4 -3
View File
@@ -1,6 +1,3 @@
import * as fs from "node:fs/promises";
import * as path from "node:path";
/**
* @file MDX plugin for ESBuild.
*
@@ -13,6 +10,10 @@ import * as path from "node:path";
* PluginBuild
* } from "esbuild"
*/
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { MonoRepoRoot } from "@goauthentik/core/paths/node";
/**
+7 -7
View File
@@ -1,11 +1,13 @@
import * as fs from "node:fs/promises";
import * as path from "node:path";
/**
* @file ESBuild script for building the authentik web UI.
*
* @import { BuildOptions } from "esbuild";
*/
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { cssAssetPlugin } from "#bundler/css-assets-plugin/node";
import { mdxPlugin } from "#bundler/mdx-plugin/node";
import { createBundleDefinitions } from "#bundler/utils/node";
import { DistDirectory, EntryPoint, PackageRoot } from "#paths/node";
@@ -40,11 +42,8 @@ const BASE_ESBUILD_OPTIONS = {
legalComments: "external",
splitting: true,
treeShaking: true,
external: ["*.woff", "*.woff2"],
tsconfig: path.resolve(PackageRoot, "tsconfig.build.json"),
loader: {
".css": "text",
},
plugins: [
copy({
assets: [
@@ -75,6 +74,7 @@ const BASE_ESBUILD_OPTIONS = {
path: true,
},
}),
cssAssetPlugin(),
mdxPlugin({
root: MonoRepoRoot,
}),
+25
View File
@@ -35,6 +35,31 @@
--ak-navbar--height: 7rem;
}
/* #region Fonts */
body {
--pf-global--FontFamily--sans-serif:
RedHatVF, "RedHatText", "Overpass", overpass, helvetica, arial, sans-serif;
--pf-global--FontFamily--heading--sans-serif:
RedHatDisplayVF, "RedHatDisplay", "Overpass", overpass, helvetica, arial, sans-serif;
--pf-global--FontFamily--monospace:
RedHatMonoVF, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace;
}
code,
pre {
/*
The variable weight is a bit too thin compared to the fixed weight.
So we'll use a slightly larger value here to compensate.
*/
font-weight: 500;
}
/* #endregion */
.pf-c-form__group {
--pf-c-form--m-horizontal__group-label--md--GridColumnWidth: minmax(max-content, 9.375rem);
column-gap: var(--pf-global--spacer--md);
+19 -5
View File
@@ -41,6 +41,14 @@ export class RouteMatch {
}
}
export function createPathnameHash(
hashRoute?: string | null,
basePath = location.pathname,
): string {
if (!hashRoute) return basePath;
return `${basePath}#${hashRoute}`;
}
export function getURLParam<T>(key: string, fallback: T): T {
const params = getURLParams();
if (key in params) {
@@ -64,13 +72,18 @@ export function getURLParams(): { [key: string]: unknown } {
}
export function setURLParams(params: { [key: string]: unknown }, replace = true): void {
const paramsString = JSON.stringify(params);
const currentUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
const newUrl = `#${currentUrl};${encodeURIComponent(paramsString)}`;
const serializedParams = JSON.stringify(params);
const [currentRoute] = window.location.hash.slice(1).split(ROUTE_SEPARATOR);
const nextPathname = createPathnameHash(
`${currentRoute};${encodeURIComponent(serializedParams)}`,
);
if (replace) {
history.replaceState(undefined, "", newUrl);
history.replaceState(undefined, "", nextPathname);
} else {
history.pushState(undefined, "", newUrl);
history.pushState(undefined, "", nextPathname);
}
}
@@ -79,5 +92,6 @@ export function updateURLParams(params: { [key: string]: unknown }, replace = tr
for (const key in params) {
currentParams[key] = params[key] as string;
}
setURLParams(currentParams, replace);
}
+3 -5
View File
@@ -1,6 +1,7 @@
import { ROUTE_SEPARATOR } from "#common/constants";
import { AKElement } from "#elements/Base";
import { createPathnameHash } from "#elements/router/RouteMatch";
import { msg, str } from "@lit/localize";
import { css, CSSResult, html, nothing, TemplateResult } from "lit";
@@ -89,10 +90,7 @@ export class SidebarItem extends AKElement {
public current?: boolean;
@property({ type: Boolean })
public isAbsoluteLink = false;
@property({ type: Boolean })
public highlight?: boolean;
public highlight = false;
public parent?: SidebarItem;
@@ -217,8 +215,8 @@ export class SidebarItem extends AKElement {
renderWithPath() {
return html`
<a
href=${createPathnameHash(this.path)}
id="sidebar-nav-link-${this.path}"
href="${this.isAbsoluteLink ? "" : "#"}${this.path}"
class="pf-c-nav__link ${this.current ? "pf-m-current" : ""}"
aria-current=${ifDefined(this.current ? "page" : undefined)}
>