web: full web components part 1 (#4964)
* migrate loading Signed-off-by: Jens Langhammer <jens@goauthentik.io> * migrate api browser Signed-off-by: Jens Langhammer <jens@goauthentik.io> * migrate base css Signed-off-by: Jens Langhammer <jens@goauthentik.io> * move tenant fetching to base interface Signed-off-by: Jens Langhammer <jens@goauthentik.io> * import pre-loaded stages in flow interface and not executor to strip down executor size Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix redirect and such Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
bebf18f257
commit
e2d3a95c80
|
@ -7,82 +7,13 @@ API Browser - {{ tenant.branding_title }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script type="module" src="{% static 'dist/rapidoc-min.js' %}"></script>
|
<script src="{% static 'dist/standalone/api-browser/index.js' %}?version={{ version }}" type="module"></script>
|
||||||
<script>
|
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)">
|
||||||
function getCookie(name) {
|
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
|
||||||
let cookieValue = "";
|
<link rel="icon" href="{{ tenant.branding_favicon }}">
|
||||||
if (document.cookie && document.cookie !== "") {
|
<link rel="shortcut icon" href="{{ tenant.branding_favicon }}">
|
||||||
const cookies = document.cookie.split(";");
|
|
||||||
for (let i = 0; i < cookies.length; i++) {
|
|
||||||
const cookie = cookies[i].trim();
|
|
||||||
// Does this cookie string begin with the name we want?
|
|
||||||
if (cookie.substring(0, name.length + 1) === name + "=") {
|
|
||||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cookieValue;
|
|
||||||
}
|
|
||||||
window.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
const rapidocEl = document.querySelector('rapi-doc');
|
|
||||||
rapidocEl.addEventListener('before-try', (e) => {
|
|
||||||
e.detail.request.headers.append('X-authentik-CSRF', getCookie("authentik_csrf"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
img.logo {
|
|
||||||
width: 100%;
|
|
||||||
padding: 1rem 0.5rem 1.5rem 0.5rem;
|
|
||||||
min-height: 48px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<rapi-doc
|
<ak-api-browser schemaPath="{{ path }}"></ak-api-browser>
|
||||||
spec-url="{{ path }}"
|
|
||||||
heading-text=""
|
|
||||||
theme="light"
|
|
||||||
render-style="read"
|
|
||||||
default-schema-tab="schema"
|
|
||||||
primary-color="#fd4b2d"
|
|
||||||
nav-bg-color="#212427"
|
|
||||||
bg-color="#000000"
|
|
||||||
text-color="#000000"
|
|
||||||
nav-text-color="#ffffff"
|
|
||||||
nav-hover-bg-color="#3c3f42"
|
|
||||||
nav-accent-color="#4f5255"
|
|
||||||
nav-hover-text-color="#ffffff"
|
|
||||||
use-path-in-nav-bar="true"
|
|
||||||
nav-item-spacing="relaxed"
|
|
||||||
allow-server-selection="false"
|
|
||||||
show-header="false"
|
|
||||||
allow-spec-url-load="false"
|
|
||||||
allow-spec-file-load="false">
|
|
||||||
<div slot="nav-logo">
|
|
||||||
<img alt="authentik Logo" class="logo" src="{% static 'dist/assets/icons/icon_left_brand.png' %}" />
|
|
||||||
</div>
|
|
||||||
</rapi-doc>
|
|
||||||
<script>
|
|
||||||
const rapidoc = document.querySelector("rapi-doc");
|
|
||||||
const matcher = window.matchMedia("(prefers-color-scheme: light)");
|
|
||||||
const changer = (ev) => {
|
|
||||||
const style = getComputedStyle(document.documentElement);
|
|
||||||
let bg, text = "";
|
|
||||||
if (matcher.matches) {
|
|
||||||
bg = style.getPropertyValue('--pf-global--BackgroundColor--light-300');
|
|
||||||
text = style.getPropertyValue('--pf-global--Color--300');
|
|
||||||
} else {
|
|
||||||
bg = style.getPropertyValue('--ak-dark-background');
|
|
||||||
text = style.getPropertyValue('--ak-dark-foreground');
|
|
||||||
}
|
|
||||||
rapidoc.attributes.getNamedItem("bg-color").value = bg.trim();
|
|
||||||
rapidoc.attributes.getNamedItem("text-color").value = text.trim();
|
|
||||||
rapidoc.requestUpdate();
|
|
||||||
};
|
|
||||||
matcher.addEventListener("change", changer);
|
|
||||||
window.addEventListener("load", changer);
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,16 +9,13 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<title>{% block title %}{% trans title|default:tenant.branding_title %}{% endblock %}</title>
|
<title>{% block title %}{% trans title|default:tenant.branding_title %}{% endblock %}</title>
|
||||||
<link rel="shortcut icon" type="image/png" href="{% static 'dist/assets/icons/icon.png' %}">
|
<link rel="shortcut icon" type="image/png" href="{% static 'dist/assets/icons/icon.png' %}">
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly-base.css' %}">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/page.css' %}">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/empty-state.css' %}">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/spinner.css' %}">
|
|
||||||
{% 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/theme-dark.css' %}" media="(prefers-color-scheme: dark)">
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/theme-dark.css' %}" media="(prefers-color-scheme: dark)">
|
||||||
<link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
|
<link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
|
||||||
<script src="{% static 'dist/poly.js' %}" type="module"></script>
|
<script src="{% static 'dist/poly.js' %}?version={{ version }}" type="module"></script>
|
||||||
|
<script src="{% static 'dist/standalone/loading/index.js' %}?version={{ version }}" type="module"></script>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
<meta name="sentry-trace" content="{{ sentry_trace }}" />
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{% extends "base/skeleton.html" %}
|
{% extends "base/skeleton.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% static 'dist/admin/AdminInterface.js' %}?version={{ version }}" type="module"></script>
|
<script src="{% static 'dist/admin/AdminInterface.js' %}?version={{ version }}" type="module"></script>
|
||||||
|
@ -15,19 +14,6 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
<ak-interface-admin>
|
<ak-interface-admin>
|
||||||
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
|
<ak-loading></ak-loading>
|
||||||
<div class="pf-c-empty-state" style="height: 100vh;">
|
|
||||||
<div class="pf-c-empty-state__content">
|
|
||||||
<span class="pf-c-spinner pf-m-xl pf-c-empty-state__icon" role="progressbar" aria-valuetext="{% trans 'Loading...' %}">
|
|
||||||
<span class="pf-c-spinner__clipper"></span>
|
|
||||||
<span class="pf-c-spinner__lead-ball"></span>
|
|
||||||
<span class="pf-c-spinner__tail-ball"></span>
|
|
||||||
</span>
|
|
||||||
<h1 class="pf-c-title pf-m-lg">
|
|
||||||
{% trans "Loading..." %}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</ak-interface-admin>
|
</ak-interface-admin>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{% extends "base/skeleton.html" %}
|
{% extends "base/skeleton.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block head_before %}
|
{% block head_before %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
@ -31,19 +30,6 @@ window.authentik.flow = {
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
<ak-flow-executor>
|
<ak-flow-executor>
|
||||||
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
|
<ak-loading></ak-loading>
|
||||||
<div class="pf-c-empty-state" style="height: 100vh;">
|
|
||||||
<div class="pf-c-empty-state__content">
|
|
||||||
<span class="pf-c-spinner pf-m-xl pf-c-empty-state__icon" role="progressbar" aria-valuetext="{% trans 'Loading...' %}">
|
|
||||||
<span class="pf-c-spinner__clipper"></span>
|
|
||||||
<span class="pf-c-spinner__lead-ball"></span>
|
|
||||||
<span class="pf-c-spinner__tail-ball"></span>
|
|
||||||
</span>
|
|
||||||
<h1 class="pf-c-title pf-m-lg">
|
|
||||||
{% trans "Loading..." %}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</ak-flow-executor>
|
</ak-flow-executor>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{% extends "base/skeleton.html" %}
|
{% extends "base/skeleton.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="{% static 'dist/user/UserInterface.js' %}?version={{ version }}" type="module"></script>
|
<script src="{% static 'dist/user/UserInterface.js' %}?version={{ version }}" type="module"></script>
|
||||||
|
@ -15,19 +14,6 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<ak-message-container></ak-message-container>
|
<ak-message-container></ak-message-container>
|
||||||
<ak-interface-user>
|
<ak-interface-user>
|
||||||
<section class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl">
|
<ak-loading></ak-loading>
|
||||||
<div class="pf-c-empty-state" style="height: 100vh;">
|
|
||||||
<div class="pf-c-empty-state__content">
|
|
||||||
<span class="pf-c-spinner pf-m-xl pf-c-empty-state__icon" role="progressbar" aria-valuetext="{% trans 'Loading...' %}">
|
|
||||||
<span class="pf-c-spinner__clipper"></span>
|
|
||||||
<span class="pf-c-spinner__lead-ball"></span>
|
|
||||||
<span class="pf-c-spinner__tail-ball"></span>
|
|
||||||
</span>
|
|
||||||
<h1 class="pf-c-title pf-m-lg">
|
|
||||||
{% trans "Loading..." %}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</ak-interface-user>
|
</ak-interface-user>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -14,28 +14,10 @@ const D3_WARNING = /Circular dependency.*d3-[interpolate|selection]/;
|
||||||
const extensions = [".js", ".jsx", ".ts", ".tsx"];
|
const extensions = [".js", ".jsx", ".ts", ".tsx"];
|
||||||
|
|
||||||
export const resources = [
|
export const resources = [
|
||||||
{ src: "node_modules/rapidoc/dist/rapidoc-min.js", dest: "dist/" },
|
|
||||||
|
|
||||||
{
|
{
|
||||||
src: "node_modules/@patternfly/patternfly/patternfly.min.css",
|
src: "node_modules/@patternfly/patternfly/patternfly.min.css",
|
||||||
dest: "dist/",
|
dest: "dist/",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
src: "node_modules/@patternfly/patternfly/patternfly-base.css",
|
|
||||||
dest: "dist/",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "node_modules/@patternfly/patternfly/components/Page/page.css",
|
|
||||||
dest: "dist/",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "node_modules/@patternfly/patternfly/components/EmptyState/empty-state.css",
|
|
||||||
dest: "dist/",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "node_modules/@patternfly/patternfly/components/Spinner/spinner.css",
|
|
||||||
dest: "dist/",
|
|
||||||
},
|
|
||||||
{ src: "src/common/styles/*", dest: "dist/" },
|
{ src: "src/common/styles/*", dest: "dist/" },
|
||||||
{ src: "src/custom.css", dest: "dist/" },
|
{ src: "src/custom.css", dest: "dist/" },
|
||||||
|
|
||||||
|
@ -132,8 +114,25 @@ export const POLY = {
|
||||||
].filter((p) => p),
|
].filter((p) => p),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const standalone = ["api-browser", "loading"].map((input) => {
|
||||||
|
return {
|
||||||
|
input: `./src/standalone/${input}`,
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
format: "es",
|
||||||
|
dir: `dist/standalone/${input}`,
|
||||||
|
sourcemap: true,
|
||||||
|
manualChunks: manualChunks,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
...defaultOptions,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
POLY,
|
POLY,
|
||||||
|
// Standalone
|
||||||
|
...standalone,
|
||||||
// Flow interface
|
// Flow interface
|
||||||
{
|
{
|
||||||
input: "./src/flow/FlowInterface.ts",
|
input: "./src/flow/FlowInterface.ts",
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import { POLY } from "./rollup.config";
|
import { POLY, standalone } from "./rollup.config";
|
||||||
|
|
||||||
export default [POLY];
|
export default [POLY, ...standalone];
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
EVENT_SIDEBAR_TOGGLE,
|
EVENT_SIDEBAR_TOGGLE,
|
||||||
VERSION,
|
VERSION,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { autoDetectLanguage } from "@goauthentik/common/ui/locale";
|
import { autoDetectLanguage } from "@goauthentik/common/ui/locale";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
|
@ -105,6 +106,7 @@ export class AdminInterface extends Interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
|
configureSentry(true);
|
||||||
this.version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
this.version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
||||||
this.user = await me();
|
this.user = await me();
|
||||||
if (!this.user.user.isSuperuser && this.user.user.pk > 0) {
|
if (!this.user.user.isSuperuser && this.user.user.pk > 0) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
|
import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
|
||||||
import { DEFAULT_CONFIG, tenant } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { first } from "@goauthentik/common/utils";
|
import { first } from "@goauthentik/common/utils";
|
||||||
|
import { rootInterface } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
|
@ -10,7 +11,7 @@ import "@goauthentik/elements/forms/SearchSelect";
|
||||||
import { t } from "@lingui/macro";
|
import { t } from "@lingui/macro";
|
||||||
|
|
||||||
import { TemplateResult, html } from "lit";
|
import { TemplateResult, html } from "lit";
|
||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -19,7 +20,6 @@ import {
|
||||||
CoreGroupsListRequest,
|
CoreGroupsListRequest,
|
||||||
CryptoApi,
|
CryptoApi,
|
||||||
CryptoCertificatekeypairsListRequest,
|
CryptoCertificatekeypairsListRequest,
|
||||||
CurrentTenant,
|
|
||||||
Flow,
|
Flow,
|
||||||
FlowsApi,
|
FlowsApi,
|
||||||
FlowsInstancesListDesignationEnum,
|
FlowsInstancesListDesignationEnum,
|
||||||
|
@ -32,14 +32,10 @@ import {
|
||||||
|
|
||||||
@customElement("ak-provider-ldap-form")
|
@customElement("ak-provider-ldap-form")
|
||||||
export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
|
export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
|
||||||
@state()
|
|
||||||
tenant?: CurrentTenant;
|
|
||||||
async loadInstance(pk: number): Promise<LDAPProvider> {
|
async loadInstance(pk: number): Promise<LDAPProvider> {
|
||||||
const provider = await new ProvidersApi(DEFAULT_CONFIG).providersLdapRetrieve({
|
return new ProvidersApi(DEFAULT_CONFIG).providersLdapRetrieve({
|
||||||
id: pk,
|
id: pk,
|
||||||
});
|
});
|
||||||
this.tenant = await tenant();
|
|
||||||
return provider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getSuccessMessage(): string {
|
getSuccessMessage(): string {
|
||||||
|
@ -101,7 +97,7 @@ export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
|
||||||
return flow?.pk;
|
return flow?.pk;
|
||||||
}}
|
}}
|
||||||
.selected=${(flow: Flow): boolean => {
|
.selected=${(flow: Flow): boolean => {
|
||||||
let selected = flow.pk === this.tenant?.flowAuthentication;
|
let selected = flow.pk === rootInterface()?.tenant?.flowAuthentication;
|
||||||
if (this.instance?.authorizationFlow === flow.pk) {
|
if (this.instance?.authorizationFlow === flow.pk) {
|
||||||
selected = true;
|
selected = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
.ak-static-page h1 {
|
|
||||||
color: var(--ak-dark-foreground);
|
|
||||||
}
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--ak-dark-background) !important;
|
background-color: var(--ak-dark-background) !important;
|
||||||
}
|
}
|
||||||
:root {
|
:root {
|
||||||
--pf-global--Color--100: var(--ak-dark-foreground);
|
--pf-global--Color--100: var(--ak-dark-foreground) !important;
|
||||||
--pf-c-page__main-section--m-light--BackgroundColor: var(--ak-dark-background-darker);
|
--pf-c-page__main-section--m-light--BackgroundColor: var(--ak-dark-background-darker);
|
||||||
--pf-global--link--Color: var(--ak-dark-foreground-link);
|
--pf-global--link--Color: var(--ak-dark-foreground-link) !important;
|
||||||
}
|
}
|
||||||
.pf-c-radio {
|
.pf-c-radio {
|
||||||
--pf-c-radio__label--Color: var(--ak-dark-foreground);
|
--pf-c-radio__label--Color: var(--ak-dark-foreground);
|
||||||
|
|
|
@ -41,7 +41,7 @@ export function me(): Promise<SessionUser> {
|
||||||
settings: {},
|
settings: {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (ex.response.status === 401 || ex.response.status === 403) {
|
if (ex.response?.status === 401 || ex.response?.status === 403) {
|
||||||
const relativeUrl = window.location
|
const relativeUrl = window.location
|
||||||
.toString()
|
.toString()
|
||||||
.substring(window.location.origin.length);
|
.substring(window.location.origin.length);
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
import { tenant } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_LOCALE_CHANGE, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
import { EVENT_LOCALE_CHANGE, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||||
|
|
||||||
import { LitElement } from "lit";
|
import { LitElement } from "lit";
|
||||||
|
import { state } from "lit/decorators.js";
|
||||||
|
|
||||||
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
||||||
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
|
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
|
||||||
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
import { UiThemeEnum } from "@goauthentik/api";
|
import { CurrentTenant, UiThemeEnum } from "@goauthentik/api";
|
||||||
|
|
||||||
export function rootInterface(): Interface | undefined {
|
export function rootInterface(): Interface | undefined {
|
||||||
const el = Array.from(document.body.querySelectorAll("*")).filter(
|
const el = Array.from(document.body.querySelectorAll("*")).filter(
|
||||||
|
@ -165,6 +168,15 @@ export class AKElement extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Interface extends AKElement {
|
export class Interface extends AKElement {
|
||||||
|
@state()
|
||||||
|
tenant?: CurrentTenant;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
document.adoptedStyleSheets = [...document.adoptedStyleSheets, PFBase];
|
||||||
|
tenant().then((tenant) => (this.tenant = tenant));
|
||||||
|
}
|
||||||
|
|
||||||
_activateTheme(root: AdoptedStyleSheetsElement, theme: UiThemeEnum): void {
|
_activateTheme(root: AdoptedStyleSheetsElement, theme: UiThemeEnum): void {
|
||||||
super._activateTheme(root, theme);
|
super._activateTheme(root, theme);
|
||||||
super._activateTheme(document, theme);
|
super._activateTheme(document, theme);
|
||||||
|
|
|
@ -34,7 +34,6 @@ export class AggregateCard extends AKElement {
|
||||||
.center-value {
|
.center-value {
|
||||||
font-size: var(--pf-global--icon--FontSize--lg);
|
font-size: var(--pf-global--icon--FontSize--lg);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--pf-global--Color--100);
|
|
||||||
}
|
}
|
||||||
.subtext {
|
.subtext {
|
||||||
font-size: var(--pf-global--FontSize--sm);
|
font-size: var(--pf-global--FontSize--sm);
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { tenant } from "@goauthentik/common/api/config";
|
|
||||||
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
|
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
|
||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
|
||||||
import { first } from "@goauthentik/common/utils";
|
import { first } from "@goauthentik/common/utils";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
|
|
||||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
|
@ -30,9 +28,6 @@ export const DefaultTenant: CurrentTenant = {
|
||||||
|
|
||||||
@customElement("ak-sidebar-brand")
|
@customElement("ak-sidebar-brand")
|
||||||
export class SidebarBrand extends AKElement {
|
export class SidebarBrand extends AKElement {
|
||||||
@property({ attribute: false })
|
|
||||||
tenant: CurrentTenant = DefaultTenant;
|
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
PFBase,
|
PFBase,
|
||||||
|
@ -69,11 +64,6 @@ export class SidebarBrand extends AKElement {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated(): void {
|
|
||||||
configureSentry(true);
|
|
||||||
tenant().then((tenant) => (this.tenant = tenant));
|
|
||||||
}
|
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
return html` ${window.innerWidth <= MIN_WIDTH
|
return html` ${window.innerWidth <= MIN_WIDTH
|
||||||
? html`
|
? html`
|
||||||
|
@ -95,7 +85,10 @@ export class SidebarBrand extends AKElement {
|
||||||
<a href="#/" class="pf-c-page__header-brand-link">
|
<a href="#/" class="pf-c-page__header-brand-link">
|
||||||
<div class="pf-c-brand ak-brand">
|
<div class="pf-c-brand ak-brand">
|
||||||
<img
|
<img
|
||||||
src="${first(this.tenant.brandingLogo, DefaultTenant.brandingLogo)}"
|
src="${first(
|
||||||
|
rootInterface()?.tenant?.brandingLogo,
|
||||||
|
DefaultTenant.brandingLogo,
|
||||||
|
)}"
|
||||||
alt="authentik Logo"
|
alt="authentik Logo"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -12,17 +12,7 @@ import { Interface } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/LoadingOverlay";
|
import "@goauthentik/elements/LoadingOverlay";
|
||||||
import "@goauthentik/flow/stages/FlowErrorStage";
|
import "@goauthentik/flow/stages/FlowErrorStage";
|
||||||
import "@goauthentik/flow/stages/RedirectStage";
|
import "@goauthentik/flow/stages/RedirectStage";
|
||||||
import "@goauthentik/flow/stages/access_denied/AccessDeniedStage";
|
|
||||||
// Import webauthn-related stages to prevent issues on safari
|
|
||||||
// Which is overly sensitive to allowing things only in the context of a
|
|
||||||
// user interaction
|
|
||||||
import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStage";
|
|
||||||
import "@goauthentik/flow/stages/authenticator_webauthn/WebAuthnAuthenticatorRegisterStage";
|
|
||||||
import "@goauthentik/flow/stages/autosubmit/AutosubmitStage";
|
|
||||||
import { StageHost } from "@goauthentik/flow/stages/base";
|
import { StageHost } from "@goauthentik/flow/stages/base";
|
||||||
import "@goauthentik/flow/stages/captcha/CaptchaStage";
|
|
||||||
import "@goauthentik/flow/stages/identification/IdentificationStage";
|
|
||||||
import "@goauthentik/flow/stages/password/PasswordStage";
|
|
||||||
|
|
||||||
import { t } from "@lingui/macro";
|
import { t } from "@lingui/macro";
|
||||||
|
|
||||||
|
@ -43,7 +33,6 @@ import {
|
||||||
ChallengeChoices,
|
ChallengeChoices,
|
||||||
ChallengeTypes,
|
ChallengeTypes,
|
||||||
ContextualFlowInfo,
|
ContextualFlowInfo,
|
||||||
CurrentTenant,
|
|
||||||
FlowChallengeResponseRequest,
|
FlowChallengeResponseRequest,
|
||||||
FlowErrorChallenge,
|
FlowErrorChallenge,
|
||||||
FlowsApi,
|
FlowsApi,
|
||||||
|
@ -92,9 +81,6 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
@property({ type: Boolean })
|
@property({ type: Boolean })
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
tenant!: CurrentTenant;
|
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
inspectorOpen = false;
|
inspectorOpen = false;
|
||||||
|
|
||||||
|
@ -186,7 +172,6 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
this.addEventListener(EVENT_FLOW_INSPECTOR_TOGGLE, () => {
|
this.addEventListener(EVENT_FLOW_INSPECTOR_TOGGLE, () => {
|
||||||
this.inspectorOpen = !this.inspectorOpen;
|
this.inspectorOpen = !this.inspectorOpen;
|
||||||
});
|
});
|
||||||
tenant().then((tenant) => (this.tenant = tenant));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTheme(): Promise<UiThemeEnum> {
|
async getTheme(): Promise<UiThemeEnum> {
|
||||||
|
@ -283,25 +268,25 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
async renderChallengeNativeElement(): Promise<TemplateResult> {
|
async renderChallengeNativeElement(): Promise<TemplateResult> {
|
||||||
switch (this.challenge?.component) {
|
switch (this.challenge?.component) {
|
||||||
case "ak-stage-access-denied":
|
case "ak-stage-access-denied":
|
||||||
// Statically imported for performance reasons
|
await import("@goauthentik/flow/stages/access_denied/AccessDeniedStage");
|
||||||
return html`<ak-stage-access-denied
|
return html`<ak-stage-access-denied
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-access-denied>`;
|
></ak-stage-access-denied>`;
|
||||||
case "ak-stage-identification":
|
case "ak-stage-identification":
|
||||||
// Statically imported for performance reasons
|
await import("@goauthentik/flow/stages/identification/IdentificationStage");
|
||||||
return html`<ak-stage-identification
|
return html`<ak-stage-identification
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-identification>`;
|
></ak-stage-identification>`;
|
||||||
case "ak-stage-password":
|
case "ak-stage-password":
|
||||||
// Statically imported for performance reasons
|
await import("@goauthentik/flow/stages/password/PasswordStage");
|
||||||
return html`<ak-stage-password
|
return html`<ak-stage-password
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-password>`;
|
></ak-stage-password>`;
|
||||||
case "ak-stage-captcha":
|
case "ak-stage-captcha":
|
||||||
// Statically imported to prevent browsers blocking urls
|
await import("@goauthentik/flow/stages/captcha/CaptchaStage");
|
||||||
return html`<ak-stage-captcha
|
return html`<ak-stage-captcha
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
|
@ -325,7 +310,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-email>`;
|
></ak-stage-email>`;
|
||||||
case "ak-stage-autosubmit":
|
case "ak-stage-autosubmit":
|
||||||
// Statically imported for performance reasons
|
await import("@goauthentik/flow/stages/autosubmit/AutosubmitStage");
|
||||||
return html`<ak-stage-autosubmit
|
return html`<ak-stage-autosubmit
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
|
@ -368,6 +353,9 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-authenticator-sms>`;
|
></ak-stage-authenticator-sms>`;
|
||||||
case "ak-stage-authenticator-validate":
|
case "ak-stage-authenticator-validate":
|
||||||
|
await import(
|
||||||
|
"@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStage"
|
||||||
|
);
|
||||||
return html`<ak-stage-authenticator-validate
|
return html`<ak-stage-authenticator-validate
|
||||||
.host=${this as StageHost}
|
.host=${this as StageHost}
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
|
@ -411,10 +399,9 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
.challenge=${this.challenge}
|
.challenge=${this.challenge}
|
||||||
></ak-stage-flow-error>`;
|
></ak-stage-flow-error>`;
|
||||||
default:
|
default:
|
||||||
break;
|
|
||||||
}
|
|
||||||
return html`Invalid native challenge element`;
|
return html`Invalid native challenge element`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async renderChallenge(): Promise<TemplateResult> {
|
async renderChallenge(): Promise<TemplateResult> {
|
||||||
if (!this.challenge) {
|
if (!this.challenge) {
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
import { autoDetectLanguage } from "@goauthentik/common/ui/locale";
|
import { autoDetectLanguage } from "@goauthentik/common/ui/locale";
|
||||||
import "@goauthentik/elements/messages/MessageContainer";
|
import "@goauthentik/elements/messages/MessageContainer";
|
||||||
import "@goauthentik/flow/FlowExecutor";
|
import "@goauthentik/flow/FlowExecutor";
|
||||||
|
// Statically import some stages to speed up load speed
|
||||||
|
import "@goauthentik/flow/stages/access_denied/AccessDeniedStage";
|
||||||
|
// Import webauthn-related stages to prevent issues on safari
|
||||||
|
// Which is overly sensitive to allowing things only in the context of a
|
||||||
|
// user interaction
|
||||||
|
import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStage";
|
||||||
|
import "@goauthentik/flow/stages/authenticator_webauthn/WebAuthnAuthenticatorRegisterStage";
|
||||||
|
import "@goauthentik/flow/stages/autosubmit/AutosubmitStage";
|
||||||
|
import "@goauthentik/flow/stages/captcha/CaptchaStage";
|
||||||
|
import "@goauthentik/flow/stages/identification/IdentificationStage";
|
||||||
|
import "@goauthentik/flow/stages/password/PasswordStage";
|
||||||
|
|
||||||
|
// end of stage import
|
||||||
|
|
||||||
autoDetectLanguage();
|
autoDetectLanguage();
|
||||||
|
|
|
@ -44,7 +44,7 @@ export class AuthenticatorValidateStage
|
||||||
return this.host.loading;
|
return this.host.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
get tenant(): CurrentTenant {
|
get tenant(): CurrentTenant | undefined {
|
||||||
return this.host.tenant;
|
return this.host.tenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ export interface StageHost {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
submit(payload: unknown): Promise<boolean>;
|
submit(payload: unknown): Promise<boolean>;
|
||||||
|
|
||||||
readonly tenant: CurrentTenant;
|
readonly tenant?: CurrentTenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readFileAsync(file: Blob) {
|
export function readFileAsync(file: Blob) {
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
|
import { first, getCookie } from "@goauthentik/common/utils";
|
||||||
|
import { Interface } from "@goauthentik/elements/Base";
|
||||||
|
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
|
||||||
|
import "rapidoc";
|
||||||
|
|
||||||
|
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
|
import { UiThemeEnum } from "@goauthentik/api";
|
||||||
|
|
||||||
|
@customElement("ak-api-browser")
|
||||||
|
export class APIBrowser extends Interface {
|
||||||
|
@property()
|
||||||
|
schemaPath?: string;
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
css`
|
||||||
|
img.logo {
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem 0.5rem 1.5rem 0.5rem;
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@state()
|
||||||
|
bgColor = "#000000";
|
||||||
|
|
||||||
|
@state()
|
||||||
|
textColor = "#000000";
|
||||||
|
|
||||||
|
firstUpdated(): void {
|
||||||
|
this.addEventListener(EVENT_THEME_CHANGE, ((ev: CustomEvent<UiThemeEnum>) => {
|
||||||
|
const style = getComputedStyle(document.documentElement);
|
||||||
|
if (ev.detail === UiThemeEnum.Light) {
|
||||||
|
this.bgColor = style
|
||||||
|
.getPropertyValue("--pf-global--BackgroundColor--light-300")
|
||||||
|
.trim();
|
||||||
|
this.textColor = style.getPropertyValue("--pf-global--Color--300").trim();
|
||||||
|
} else {
|
||||||
|
this.bgColor = style.getPropertyValue("--ak-dark-background").trim();
|
||||||
|
this.textColor = style.getPropertyValue("--ak-dark-foreground").trim();
|
||||||
|
}
|
||||||
|
}) as EventListener);
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent(EVENT_THEME_CHANGE, {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
detail: UiThemeEnum.Automatic,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<rapi-doc
|
||||||
|
spec-url=${ifDefined(this.schemaPath)}
|
||||||
|
heading-text=""
|
||||||
|
theme="light"
|
||||||
|
render-style="read"
|
||||||
|
default-schema-tab="schema"
|
||||||
|
primary-color="#fd4b2d"
|
||||||
|
nav-bg-color="#212427"
|
||||||
|
bg-color=${this.bgColor}
|
||||||
|
text-color=${this.textColor}
|
||||||
|
nav-text-color="#ffffff"
|
||||||
|
nav-hover-bg-color="#3c3f42"
|
||||||
|
nav-accent-color="#4f5255"
|
||||||
|
nav-hover-text-color="#ffffff"
|
||||||
|
use-path-in-nav-bar="true"
|
||||||
|
nav-item-spacing="relaxed"
|
||||||
|
allow-server-selection="false"
|
||||||
|
show-header="false"
|
||||||
|
allow-spec-url-load="false"
|
||||||
|
allow-spec-file-load="false"
|
||||||
|
@before-try=${(
|
||||||
|
e: CustomEvent<{
|
||||||
|
request: {
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
}>,
|
||||||
|
) => {
|
||||||
|
e.detail.request.headers.append(
|
||||||
|
"X-authentik-CSRF",
|
||||||
|
getCookie("authentik_csrf"),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div slot="nav-logo">
|
||||||
|
<img
|
||||||
|
alt="authentik Logo"
|
||||||
|
class="logo"
|
||||||
|
src="${first(this.tenant?.brandingLogo, DefaultTenant.brandingLogo)}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</rapi-doc>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
|
import { Interface } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
|
import { t } from "@lingui/macro";
|
||||||
|
|
||||||
|
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||||
|
import { customElement } from "lit/decorators.js";
|
||||||
|
|
||||||
|
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||||
|
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
|
import PFSpinner from "@patternfly/patternfly/components/Spinner/spinner.css";
|
||||||
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
|
|
||||||
|
import { UiThemeEnum } from "@goauthentik/api";
|
||||||
|
|
||||||
|
@customElement("ak-loading")
|
||||||
|
export class Loading extends Interface {
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
PFBase,
|
||||||
|
PFPage,
|
||||||
|
PFSpinner,
|
||||||
|
PFEmptyState,
|
||||||
|
css`
|
||||||
|
:host([theme="dark"]) h1 {
|
||||||
|
color: var(--ak-dark-foreground);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTheme(): Promise<UiThemeEnum> {
|
||||||
|
return globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): TemplateResult {
|
||||||
|
return html` <section
|
||||||
|
class="ak-static-page pf-c-page__main-section pf-m-no-padding-mobile pf-m-xl"
|
||||||
|
>
|
||||||
|
<div class="pf-c-empty-state" style="height: 100vh;">
|
||||||
|
<div class="pf-c-empty-state__content">
|
||||||
|
<span
|
||||||
|
class="pf-c-spinner pf-m-xl"
|
||||||
|
role="progressbar"
|
||||||
|
aria-valuetext="${t`Loading...`}"
|
||||||
|
>
|
||||||
|
<span class="pf-c-spinner__clipper"></span>
|
||||||
|
<span class="pf-c-spinner__lead-ball"></span>
|
||||||
|
<span class="pf-c-spinner__tail-ball"></span>
|
||||||
|
</span>
|
||||||
|
<h1 class="pf-c-title pf-m-lg">${t`Loading...`}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { DEFAULT_CONFIG, tenant } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import {
|
import {
|
||||||
EVENT_API_DRAWER_TOGGLE,
|
EVENT_API_DRAWER_TOGGLE,
|
||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
|
@ -36,7 +36,7 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||||
import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
|
import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
|
||||||
|
|
||||||
import { CurrentTenant, EventsApi, SessionUser } from "@goauthentik/api";
|
import { EventsApi, SessionUser } from "@goauthentik/api";
|
||||||
|
|
||||||
autoDetectLanguage();
|
autoDetectLanguage();
|
||||||
|
|
||||||
|
@ -50,9 +50,6 @@ export class UserInterface extends Interface {
|
||||||
|
|
||||||
ws: WebsocketClient;
|
ws: WebsocketClient;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
tenant: CurrentTenant = DefaultTenant;
|
|
||||||
|
|
||||||
@property({ type: Number })
|
@property({ type: Number })
|
||||||
notificationsCount = 0;
|
notificationsCount = 0;
|
||||||
|
|
||||||
|
@ -128,7 +125,6 @@ export class UserInterface extends Interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
this.tenant = await tenant();
|
|
||||||
this.me = await me();
|
this.me = await me();
|
||||||
this.config = await uiConfig();
|
this.config = await uiConfig();
|
||||||
const notifications = await new EventsApi(DEFAULT_CONFIG).eventsNotificationsList({
|
const notifications = await new EventsApi(DEFAULT_CONFIG).eventsNotificationsList({
|
||||||
|
@ -165,8 +161,8 @@ export class UserInterface extends Interface {
|
||||||
<a href="#/" class="pf-c-page__header-brand-link">
|
<a href="#/" class="pf-c-page__header-brand-link">
|
||||||
<img
|
<img
|
||||||
class="pf-c-brand"
|
class="pf-c-brand"
|
||||||
src="${first(this.tenant.brandingLogo, DefaultTenant.brandingLogo)}"
|
src="${first(this.tenant?.brandingLogo, DefaultTenant.brandingLogo)}"
|
||||||
alt="${(this.tenant.brandingTitle, DefaultTenant.brandingTitle)}"
|
alt="${(this.tenant?.brandingTitle, DefaultTenant.brandingTitle)}"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -62,7 +62,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
||||||
<div class="pf-c-form__horizontal-group">
|
<div class="pf-c-form__horizontal-group">
|
||||||
<div class="pf-c-form__actions">
|
<div class="pf-c-form__actions">
|
||||||
<button type="submit" class="pf-c-button pf-m-primary">${t`Save`}</button>
|
<button type="submit" class="pf-c-button pf-m-primary">${t`Save`}</button>
|
||||||
${this.host.tenant.flowUnenrollment
|
${this.host.tenant?.flowUnenrollment
|
||||||
? html` <a
|
? html` <a
|
||||||
class="pf-c-button pf-m-danger"
|
class="pf-c-button pf-m-danger"
|
||||||
href="/if/flow/${this.host.tenant.flowUnenrollment}/"
|
href="/if/flow/${this.host.tenant.flowUnenrollment}/"
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
"@goauthentik/admin/*": ["src/admin/*"],
|
"@goauthentik/admin/*": ["src/admin/*"],
|
||||||
"@goauthentik/common/*": ["src/common/*"],
|
"@goauthentik/common/*": ["src/common/*"],
|
||||||
|
"@goauthentik/docs/*": ["../website/docs/*"],
|
||||||
"@goauthentik/elements/*": ["src/elements/*"],
|
"@goauthentik/elements/*": ["src/elements/*"],
|
||||||
"@goauthentik/flow/*": ["src/flow/*"],
|
"@goauthentik/flow/*": ["src/flow/*"],
|
||||||
"@goauthentik/polyfill/*": ["src/polyfill/*"],
|
|
||||||
"@goauthentik/user/*": ["src/user/*"],
|
|
||||||
"@goauthentik/locales/*": ["src/locales/*"],
|
"@goauthentik/locales/*": ["src/locales/*"],
|
||||||
"@goauthentik/docs/*": ["../website/docs/*"]
|
"@goauthentik/polyfill/*": ["src/polyfill/*"],
|
||||||
|
"@goauthentik/standalone/*": ["src/standalone/*"],
|
||||||
|
"@goauthentik/user/*": ["src/user/*"]
|
||||||
},
|
},
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
Reference in New Issue