web/admin: rework markdown, correctly render Admonitions, fix links

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer
2022-12-19 12:48:02 +01:00
parent 39e0ed2962
commit 9d5b9204fc
6 changed files with 132 additions and 24 deletions

View File

@ -259,7 +259,20 @@ export class OAuth2ProviderViewPage extends AKElement {
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-12-col-on-2xl"
>
<div class="pf-c-card__body">
<ak-markdown .md=${MDProviderOAuth2}></ak-markdown>
<ak-markdown
.replacers=${[
(input: string) => {
if (!this.provider) {
return input;
}
return input.replaceAll(
"&lt;application slug&gt;",
this.provider.assignedApplicationSlug,
);
},
]}
.md=${MDProviderOAuth2}
></ak-markdown>
</div>
</div>
</div>`;

View File

@ -13,7 +13,6 @@ import MDTraefikStandalone from "@goauthentik/docs/providers/proxy/_traefik_stan
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/CodeMirror";
import { PFColor } from "@goauthentik/elements/Label";
import { MarkdownDocument } from "@goauthentik/elements/Markdown";
import "@goauthentik/elements/Markdown";
import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/buttons/ModalButton";
@ -104,25 +103,6 @@ export class ProxyProviderViewPage extends AKElement {
});
}
renderConfigTemplate(markdown: MarkdownDocument): MarkdownDocument {
const extHost = new URL(this.provider?.externalHost || "http://a");
// See website/docs/providers/proxy/forward_auth.mdx
if (this.provider?.mode === ProxyMode.ForwardSingle) {
markdown.html = markdown.html
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company:9000", window.location.hostname)
.replaceAll("https://app.company", extHost.toString())
.replaceAll("app.company", extHost.hostname);
} else if (this.provider?.mode == ProxyMode.ForwardDomain) {
markdown.html = markdown.html
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company:9000", extHost.toString())
.replaceAll("https://app.company", extHost.toString())
.replaceAll("app.company", extHost.hostname);
}
return markdown;
}
renderConfig(): TemplateResult {
const serves = [
{
@ -154,6 +134,29 @@ export class ProxyProviderViewPage extends AKElement {
md: MDCaddyStandalone,
},
];
const replacers = [
(input: string): string => {
if (!this.provider) {
return input;
}
const extHost = new URL(this.provider.externalHost);
// See website/docs/providers/proxy/forward_auth.mdx
if (this.provider?.mode === ProxyMode.ForwardSingle) {
return input
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company:9000", window.location.hostname)
.replaceAll("https://app.company", extHost.toString())
.replaceAll("app.company", extHost.hostname);
} else if (this.provider?.mode == ProxyMode.ForwardDomain) {
return input
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company:9000", extHost.toString())
.replaceAll("https://app.company", extHost.toString())
.replaceAll("app.company", extHost.hostname);
}
return input;
},
];
return html`<ak-tabs pageIdentifier="proxy-setup">
${serves.map((server) => {
return html`<section
@ -161,7 +164,7 @@ export class ProxyProviderViewPage extends AKElement {
data-tab-title="${server.label}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
<ak-markdown .md=${this.renderConfigTemplate(server.md)}></ak-markdown>
<ak-markdown .replacers=${replacers} .md=${server.md}></ak-markdown>
</section>`;
})}</ak-tabs
>`;

41
web/src/elements/Alert.ts Normal file
View File

@ -0,0 +1,41 @@
import { AKElement } from "@goauthentik/elements/Base";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
export enum Level {
Warning = "pf-m-warning",
Info = "pf-m-info",
Success = "pf-m-success",
Danger = "pf-m-danger",
}
@customElement("ak-alert")
export class Alert extends AKElement {
@property({ type: Boolean })
inline = false;
@property()
level: Level = Level.Warning;
static get styles(): CSSResult[] {
return [PFBase, PFAlert, AKGlobal];
}
render(): TemplateResult {
return html`<div
class="pf-c-alert ${this.inline ? html`pf-m-inline` : html``} ${this.level}"
>
<div class="pf-c-alert__icon">
<i class="fas fa-exclamation-circle"></i>
</div>
<h4 class="pf-c-alert__title">
<slot></slot>
</h4>
</div>`;
}
}

View File

@ -1,3 +1,4 @@
import "@goauthentik/elements/Alert";
import { AKElement } from "@goauthentik/elements/Base";
import { CSSResult, TemplateResult, html } from "lit";
@ -12,22 +13,66 @@ export interface MarkdownDocument {
html: string;
metadata: { [key: string]: string };
filename: string;
path: string;
}
export type Replacer = (input: string, md: MarkdownDocument) => string;
@customElement("ak-markdown")
export class Markdown extends AKElement {
@property({ attribute: false })
md?: MarkdownDocument;
@property({ attribute: false })
replacers: Replacer[] = [];
defaultReplacers: Replacer[] = [
this.replaceAdmonitions,
this.replaceList,
this.replaceRelativeLinks,
];
static get styles(): CSSResult[] {
return [PFList, PFContent, AKGlobal];
}
replaceAdmonitions(input: string): string {
const admonitionStart = /:::(\w+)<br\s\/>/gm;
const admonitionEnd = /:::/gm;
return input
.replaceAll(admonitionStart, "<ak-alert level=\"$1\">")
.replaceAll(admonitionEnd, "</ak-alert>");
}
replaceList(input: string): string {
return input.replace("<ul>", "<ul class='pf-c-list'>");
}
replaceRelativeLinks(input: string, md: MarkdownDocument): string {
const relativeLink = /href=".(.*)"/gm;
const cwd = process.env.CWD as string;
// cwd will point to $root/web, but the docs are in $root/website/docs
let relPath = md.path.replace(cwd + "site", "");
if (md.filename === "index.md") {
relPath = relPath.replace("index.md", "");
}
const baseURL = "https://goauthentik.io";
const fullURL = `${baseURL}${relPath}.$1`;
return input.replace(relativeLink, `href="${fullURL}" target="_blank"`);
}
render(): TemplateResult {
if (!this.md) {
return html``;
}
const finalHTML = this.md?.html.replace("<ul>", "<ul class='pf-c-list'>");
let finalHTML = this.md.html;
const replacers = [...this.defaultReplacers, ...this.replacers];
replacers.forEach((r) => {
if (!this.md) {
return;
}
finalHTML = r(finalHTML, this.md);
});
return html`${this.md?.metadata.title ? html`<h2>${this.md.metadata.title}</h2>` : html``}
${unsafeHTML(finalHTML)}`;
}