Compare commits
1 Commits
server-con
...
docusaurus
Author | SHA1 | Date | |
---|---|---|---|
971b9e6bca |
@ -1,14 +1,5 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
{{ config_json|json_script:":ak-config:" }}
|
|
||||||
|
|
||||||
{{ brand_json|json_script:":ak-brand:" }}
|
|
||||||
|
|
||||||
<meta name="ak-version-family" content="{{ version_family }}">
|
|
||||||
<meta name="ak-version-subdomain" content="{{ version_subdomain }}">
|
|
||||||
<meta name="ak-build" content="{{ build }}">
|
|
||||||
<meta name="ak-base-url" content="{{ base_url }}">
|
|
||||||
<meta name="ak-base-url-rel" content="{{ base_url_rel }}">
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.authentik = {
|
window.authentik = {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Interface views"""
|
"""Interface views"""
|
||||||
|
|
||||||
|
from json import dumps
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
@ -45,19 +46,14 @@ class InterfaceView(TemplateView):
|
|||||||
"""Base interface view"""
|
"""Base interface view"""
|
||||||
|
|
||||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
"""Add common context data to all interface views"""
|
kwargs["config_json"] = dumps(ConfigView(request=Request(self.request)).get_config().data)
|
||||||
|
kwargs["brand_json"] = dumps(CurrentBrandSerializer(self.request.brand).data)
|
||||||
kwargs["config_json"] = ConfigView(request=Request(self.request)).get_config().data
|
|
||||||
kwargs["brand_json"] = CurrentBrandSerializer(self.request.brand).data
|
|
||||||
|
|
||||||
kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
|
kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
|
||||||
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"
|
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"
|
||||||
|
|
||||||
kwargs["build"] = get_build_hash()
|
kwargs["build"] = get_build_hash()
|
||||||
kwargs["url_kwargs"] = self.kwargs
|
kwargs["url_kwargs"] = self.kwargs
|
||||||
kwargs["base_url"] = self.request.build_absolute_uri(CONFIG.get("web.path", "/"))
|
kwargs["base_url"] = self.request.build_absolute_uri(CONFIG.get("web.path", "/"))
|
||||||
kwargs["base_url_rel"] = CONFIG.get("web.path", "/")
|
kwargs["base_url_rel"] = CONFIG.get("web.path", "/")
|
||||||
|
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
4
packages/docusaurus-config/package-lock.json
generated
4
packages/docusaurus-config/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/docusaurus-config",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@goauthentik/docusaurus-config",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deepmerge-ts": "^7.1.5",
|
"deepmerge-ts": "^7.1.5",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/docusaurus-config",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"description": "authentik's Docusaurus config",
|
"description": "authentik's Docusaurus config",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -33,7 +33,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
|||||||
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
||||||
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
||||||
let build: string | TemplateResult = msg("Release");
|
let build: string | TemplateResult = msg("Release");
|
||||||
if (ServerContext.config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||||
build = msg("Development");
|
build = msg("Development");
|
||||||
} else if (version.buildHash !== "") {
|
} else if (version.buildHash !== "") {
|
||||||
build = html`<a
|
build = html`<a
|
||||||
@ -58,12 +58,10 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderModal() {
|
renderModal() {
|
||||||
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||||
|
|
||||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||||
product += ` ${msg("Enterprise")}`;
|
product += ` ${msg("Enterprise")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<div
|
return html`<div
|
||||||
class="pf-c-backdrop"
|
class="pf-c-backdrop"
|
||||||
@click=${(e: PointerEvent) => {
|
@click=${(e: PointerEvent) => {
|
||||||
|
@ -6,8 +6,7 @@ import {
|
|||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
EVENT_SIDEBAR_TOGGLE,
|
EVENT_SIDEBAR_TOGGLE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
||||||
@ -168,21 +167,15 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
tryInitializeSentry(ServerContext.config);
|
configureSentry(true);
|
||||||
this.user = await me();
|
this.user = await me();
|
||||||
|
|
||||||
setSentryPII(this.user.user);
|
|
||||||
|
|
||||||
const canAccessAdmin =
|
const canAccessAdmin =
|
||||||
this.user.user.isSuperuser ||
|
this.user.user.isSuperuser ||
|
||||||
// TODO: somehow add `access_admin_interface` to the API schema
|
// TODO: somehow add `access_admin_interface` to the API schema
|
||||||
this.user.user.systemPermissions.includes("access_admin_interface");
|
this.user.user.systemPermissions.includes("access_admin_interface");
|
||||||
|
|
||||||
if (!canAccessAdmin && this.user.user.pk > 0) {
|
if (!canAccessAdmin && this.user.user.pk > 0) {
|
||||||
console.debug(
|
|
||||||
"authentik/admin: User does not have access to admin interface. Redirecting...",
|
|
||||||
);
|
|
||||||
|
|
||||||
window.location.assign("/if/user/");
|
window.location.assign("/if/user/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/components/ak-toggle-group";
|
import "@goauthentik/components/ak-toggle-group";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
||||||
import "@goauthentik/elements/buttons/TokenCopyButton";
|
import "@goauthentik/elements/buttons/TokenCopyButton";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import { groupBy } from "@goauthentik/common/utils";
|
import { groupBy } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
|
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BasePropertyMappingForm } from "@goauthentik/admin/property-mappings/BasePropertyMappingForm";
|
import { BasePropertyMappingForm } from "@goauthentik/admin/property-mappings/BasePropertyMappingForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/server-context";
|
import { docLink } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
|
@ -5,8 +5,7 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
|
||||||
import "@goauthentik/components/ak-switch-input";
|
import "@goauthentik/components/ak-switch-input";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import "@goauthentik/components/ak-textarea-input";
|
import "@goauthentik/components/ak-textarea-input";
|
||||||
@ -61,9 +60,8 @@ export class KerberosSourceForm extends WithCapabilitiesConfig(BaseSourceForm<Ke
|
|||||||
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
|
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { capabilities } = ServerContext.config;
|
const c = await config();
|
||||||
|
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
@ -5,8 +5,7 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
|
||||||
import "@goauthentik/components/ak-radio-input";
|
import "@goauthentik/components/ak-radio-input";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
@ -86,9 +85,8 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
|
|||||||
oAuthSourceRequest: data as unknown as OAuthSourceRequest,
|
oAuthSourceRequest: data as unknown as OAuthSourceRequest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { capabilities } = ServerContext.config;
|
const c = await config();
|
||||||
|
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
@ -6,8 +6,7 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
|
||||||
import {
|
import {
|
||||||
CapabilitiesEnum,
|
CapabilitiesEnum,
|
||||||
WithCapabilitiesConfig,
|
WithCapabilitiesConfig,
|
||||||
@ -62,9 +61,8 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
|
|||||||
sAMLSourceRequest: data,
|
sAMLSourceRequest: data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { capabilities } = ServerContext.config;
|
const c = await config();
|
||||||
|
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import { Form } from "@goauthentik/elements/forms/Form";
|
import { Form } from "@goauthentik/elements/forms/Form";
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export class UserImpersonateForm extends Form<ImpersonationRequest> {
|
|||||||
impersonationRequest: data,
|
impersonationRequest: data,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
window.location.href = ServerContext.baseURL;
|
window.location.href = globalAK().api.base;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,22 @@ import {
|
|||||||
LoggingMiddleware,
|
LoggingMiddleware,
|
||||||
} from "@goauthentik/common/api/middleware";
|
} from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
|
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
|
|
||||||
import { Configuration, CurrentBrand } from "@goauthentik/api";
|
import { Config, Configuration, CoreApi, CurrentBrand, RootApi } from "@goauthentik/api";
|
||||||
|
|
||||||
// HACK: Workaround for ESBuild not being able to hoist import statement across entrypoints.
|
// HACK: Workaround for ESBuild not being able to hoist import statement across entrypoints.
|
||||||
// This can be removed after ESBuild uses a single build context for all entrypoints.
|
// This can be removed after ESBuild uses a single build context for all entrypoints.
|
||||||
export { CSRFHeaderName };
|
export { CSRFHeaderName };
|
||||||
|
|
||||||
|
let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
|
||||||
|
export function config(): Promise<Config> {
|
||||||
|
if (!globalConfigPromise) {
|
||||||
|
globalConfigPromise = new RootApi(DEFAULT_CONFIG).rootConfigRetrieve();
|
||||||
|
}
|
||||||
|
return globalConfigPromise;
|
||||||
|
}
|
||||||
|
|
||||||
export function brandSetFavicon(brand: CurrentBrand) {
|
export function brandSetFavicon(brand: CurrentBrand) {
|
||||||
/**
|
/**
|
||||||
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
|
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
|
||||||
@ -44,22 +52,35 @@ export function brandSetLocale(brand: CurrentBrand) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let globalBrandPromise: Promise<CurrentBrand> | undefined = Promise.resolve(globalAK().brand);
|
||||||
|
export function brand(): Promise<CurrentBrand> {
|
||||||
|
if (!globalBrandPromise) {
|
||||||
|
globalBrandPromise = new CoreApi(DEFAULT_CONFIG)
|
||||||
|
.coreBrandsCurrentRetrieve()
|
||||||
|
.then((brand) => {
|
||||||
|
brandSetFavicon(brand);
|
||||||
|
brandSetLocale(brand);
|
||||||
|
return brand;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return globalBrandPromise;
|
||||||
|
}
|
||||||
|
|
||||||
export function getMetaContent(key: string): string {
|
export function getMetaContent(key: string): string {
|
||||||
const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
|
const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
|
||||||
if (!metaEl) return "";
|
if (!metaEl) return "";
|
||||||
|
|
||||||
return metaEl.content;
|
return metaEl.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_CONFIG = new Configuration({
|
export const DEFAULT_CONFIG = new Configuration({
|
||||||
basePath: `${ServerContext.baseURL}api/v3`,
|
basePath: `${globalAK().api.base}api/v3`,
|
||||||
headers: {
|
headers: {
|
||||||
"sentry-trace": ServerContext.sentryTrace,
|
"sentry-trace": getMetaContent("sentry-trace"),
|
||||||
},
|
},
|
||||||
middleware: [
|
middleware: [
|
||||||
new CSRFMiddleware(),
|
new CSRFMiddleware(),
|
||||||
new EventMiddleware(),
|
new EventMiddleware(),
|
||||||
new LoggingMiddleware(ServerContext.brand),
|
new LoggingMiddleware(globalAK().brand),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
59
web/src/common/global.ts
Normal file
59
web/src/common/global.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
|
||||||
|
|
||||||
|
export interface GlobalAuthentik {
|
||||||
|
_converted?: boolean;
|
||||||
|
locale?: string;
|
||||||
|
flow?: {
|
||||||
|
layout: string;
|
||||||
|
};
|
||||||
|
config: Config;
|
||||||
|
brand: CurrentBrand;
|
||||||
|
versionFamily: string;
|
||||||
|
versionSubdomain: string;
|
||||||
|
build: string;
|
||||||
|
api: {
|
||||||
|
base: string;
|
||||||
|
relBase: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthentikWindow {
|
||||||
|
authentik: GlobalAuthentik;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function globalAK(): GlobalAuthentik {
|
||||||
|
const ak = (window as unknown as AuthentikWindow).authentik;
|
||||||
|
if (ak && !ak._converted) {
|
||||||
|
ak._converted = true;
|
||||||
|
ak.brand = CurrentBrandFromJSON(ak.brand);
|
||||||
|
ak.config = ConfigFromJSON(ak.config);
|
||||||
|
}
|
||||||
|
const apiBase = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||||
|
if (!ak) {
|
||||||
|
return {
|
||||||
|
config: ConfigFromJSON({
|
||||||
|
capabilities: [],
|
||||||
|
}),
|
||||||
|
brand: CurrentBrandFromJSON({
|
||||||
|
ui_footer_links: [],
|
||||||
|
}),
|
||||||
|
versionFamily: "",
|
||||||
|
versionSubdomain: "",
|
||||||
|
build: "",
|
||||||
|
api: {
|
||||||
|
base: apiBase.toString(),
|
||||||
|
relBase: apiBase.pathname,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ak;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function docLink(path: string): string {
|
||||||
|
const ak = globalAK();
|
||||||
|
// Default case or beta build which should always point to latest
|
||||||
|
if (!ak || ak.build !== "") {
|
||||||
|
return `https://goauthentik.io${path}`;
|
||||||
|
}
|
||||||
|
return `https://${ak.versionSubdomain}.goauthentik.io${path}`;
|
||||||
|
}
|
@ -1,34 +1,32 @@
|
|||||||
|
import { config } from "@goauthentik/common/api/config";
|
||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { RouteInterfaceName, readInterfaceRouteParam } from "@goauthentik/elements/router/utils";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { BrowserOptions, browserTracingIntegration, init, setTag, setUser } from "@sentry/browser";
|
import { readInterfaceRouteParam } from "@goauthentik/elements/router/utils";
|
||||||
|
import {
|
||||||
|
ErrorEvent,
|
||||||
|
EventHint,
|
||||||
|
browserTracingIntegration,
|
||||||
|
init,
|
||||||
|
setTag,
|
||||||
|
setUser,
|
||||||
|
} from "@sentry/browser";
|
||||||
|
|
||||||
import { CapabilitiesEnum, Config, ResponseError, UserSelf } from "@goauthentik/api";
|
import { CapabilitiesEnum, Config, ResponseError } from "@goauthentik/api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic error that can be thrown without triggering Sentry's reporting.
|
* A generic error that can be thrown without triggering Sentry's reporting.
|
||||||
*
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
*/
|
||||||
export class SentryIgnoredError extends Error {}
|
export class SentryIgnoredError extends Error {}
|
||||||
|
|
||||||
/**
|
export const TAG_SENTRY_COMPONENT = "authentik.component";
|
||||||
* Attempt initializing Spotlight.
|
export const TAG_SENTRY_CAPABILITIES = "authentik.capabilities";
|
||||||
*
|
|
||||||
* @see {@link https://spotlightjs.com/ Spotlight}
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
|
||||||
export async function tryInitializingSpotlight() {
|
|
||||||
return import("@spotlightjs/spotlight").then((Spotlight) =>
|
|
||||||
Spotlight.init({ injectImmediately: true }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
export async function configureSentry(canDoPpi = false): Promise<Config> {
|
||||||
* Default Sentry options for the browser.
|
const cfg = await config();
|
||||||
*
|
|
||||||
* @category Sentry
|
if (cfg.errorReporting.enabled) {
|
||||||
*/
|
init({
|
||||||
const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
dsn: cfg.errorReporting.sentryDsn,
|
||||||
ignoreErrors: [
|
ignoreErrors: [
|
||||||
/network/gi,
|
/network/gi,
|
||||||
/fetch/gi,
|
/fetch/gi,
|
||||||
@ -48,7 +46,12 @@ const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
beforeSend: (event, hint) => {
|
tracesSampleRate: cfg.errorReporting.tracesSampleRate,
|
||||||
|
environment: cfg.errorReporting.environment,
|
||||||
|
beforeSend: (
|
||||||
|
event: ErrorEvent,
|
||||||
|
hint: EventHint,
|
||||||
|
): ErrorEvent | PromiseLike<ErrorEvent | null> | null => {
|
||||||
if (!hint) {
|
if (!hint) {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
@ -63,69 +66,24 @@ const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
|||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
},
|
},
|
||||||
} as const satisfies BrowserOptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the given user in Sentry events.
|
|
||||||
*
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
|
||||||
export function setSentryPII(user: UserSelf): void {
|
|
||||||
console.debug("authentik/sentry: PII enabled.");
|
|
||||||
|
|
||||||
setUser({ email: user.email });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the given capabilities in Sentry events.
|
|
||||||
*
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
|
||||||
export function setSentryCapabilities(capabilities: CapabilitiesEnum[]): void {
|
|
||||||
setTag("authentik.capabilities", capabilities.join(","));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the given route interface in Sentry events.
|
|
||||||
*
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
|
||||||
export function setSentryInterface(interfaceName: RouteInterfaceName) {
|
|
||||||
setTag("authentik.component", `web/${interfaceName}}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to initialize Sentry with the given configuration.
|
|
||||||
*
|
|
||||||
* @see {@linkcode setSentryPII}
|
|
||||||
* @see {@linkcode setSentryCapabilities}
|
|
||||||
* @see {@linkcode setSentryInterface}
|
|
||||||
* @category Sentry
|
|
||||||
*/
|
|
||||||
export function tryInitializeSentry({ errorReporting, capabilities }: Config): void {
|
|
||||||
if (!errorReporting.enabled) return;
|
|
||||||
|
|
||||||
init({
|
|
||||||
...DEFAULT_SENTRY_BROWSER_OPTIONS,
|
|
||||||
dsn: errorReporting.sentryDsn,
|
|
||||||
tracesSampleRate: errorReporting.tracesSampleRate,
|
|
||||||
environment: errorReporting.environment,
|
|
||||||
enabled: process.env.NODE_ENV !== "development",
|
|
||||||
});
|
|
||||||
|
|
||||||
setSentryCapabilities(capabilities);
|
|
||||||
setSentryInterface(readInterfaceRouteParam());
|
|
||||||
|
|
||||||
if (
|
|
||||||
process.env.NODE_ENV === "development" &&
|
|
||||||
capabilities.includes(CapabilitiesEnum.CanDebug)
|
|
||||||
) {
|
|
||||||
tryInitializingSpotlight()
|
|
||||||
.then(() => {
|
|
||||||
console.debug("authentik/sentry: Sentry with Spotlight enabled.");
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.warn("authentik/sentry: Failed to load Spotlight", err);
|
|
||||||
});
|
});
|
||||||
|
setTag(TAG_SENTRY_CAPABILITIES, cfg.capabilities.join(","));
|
||||||
|
if (window.location.pathname.includes("if/")) {
|
||||||
|
setTag(TAG_SENTRY_COMPONENT, `web/${readInterfaceRouteParam()}`);
|
||||||
}
|
}
|
||||||
|
if (cfg.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||||
|
const Spotlight = await import("@spotlightjs/spotlight");
|
||||||
|
|
||||||
|
Spotlight.init({ injectImmediately: true });
|
||||||
|
}
|
||||||
|
if (cfg.errorReporting.sendPii && canDoPpi) {
|
||||||
|
me().then((user) => {
|
||||||
|
setUser({ email: user.user.email });
|
||||||
|
console.debug("authentik/config: Sentry with PII enabled.");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.debug("authentik/config: Sentry enabled.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cfg;
|
||||||
}
|
}
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file Server context singleton.
|
|
||||||
*/
|
|
||||||
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
|
|
||||||
|
|
||||||
function readMetaElement(key: string, fallback: string = ""): string {
|
|
||||||
const metaElement = document.querySelector<HTMLMetaElement>(`meta[name="${key}"]`);
|
|
||||||
const value = metaElement?.getAttribute("content") || fallback;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ServerContextValue {
|
|
||||||
/**
|
|
||||||
* Server-injected authentik configuration.
|
|
||||||
*/
|
|
||||||
config: Readonly<Config>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Brand information used to customize the UI.
|
|
||||||
*/
|
|
||||||
brand: Readonly<CurrentBrand>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A semantic versioning string representing the current version of authentik.
|
|
||||||
*/
|
|
||||||
versionFamily: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A subdomain-compatible version string representing the current version of authentik.
|
|
||||||
*/
|
|
||||||
versionSubdomain: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A build hash string representing the current build of authentik.
|
|
||||||
*/
|
|
||||||
build: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base URL of the authentik instance.
|
|
||||||
*/
|
|
||||||
baseURL: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The relative base URL of the authentik instance.
|
|
||||||
*/
|
|
||||||
baseURLRelative: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The layout of the flow, if any.
|
|
||||||
*/
|
|
||||||
flowLayout: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Sentry trace ID for the current request.
|
|
||||||
*/
|
|
||||||
sentryTrace: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the server context from the DOM.
|
|
||||||
*/
|
|
||||||
export function refreshServerContext(): Readonly<ServerContextValue> {
|
|
||||||
const configElement = document.getElementById(":ak-config:");
|
|
||||||
|
|
||||||
const config = configElement?.textContent
|
|
||||||
? ConfigFromJSON(JSON.parse(configElement.textContent))
|
|
||||||
: ConfigFromJSON({
|
|
||||||
capabilities: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
const brandElement = document.getElementById(":ak-brand:");
|
|
||||||
|
|
||||||
const brand = brandElement?.textContent
|
|
||||||
? CurrentBrandFromJSON(JSON.parse(brandElement.textContent))
|
|
||||||
: CurrentBrandFromJSON({
|
|
||||||
ui_footer_links: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
const apiBaseURL = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
|
||||||
|
|
||||||
const value: ServerContextValue = {
|
|
||||||
sentryTrace: readMetaElement("sentry-trace"),
|
|
||||||
baseURL: readMetaElement("ak-base-url") || apiBaseURL.toString(),
|
|
||||||
baseURLRelative: readMetaElement("ak-base-url-rel"),
|
|
||||||
|
|
||||||
versionFamily: readMetaElement("ak-version-family"),
|
|
||||||
versionSubdomain: readMetaElement("ak-version-subdomain"),
|
|
||||||
|
|
||||||
build: readMetaElement("ak-build"),
|
|
||||||
|
|
||||||
flowLayout: readMetaElement("ak-flow-layout"),
|
|
||||||
config,
|
|
||||||
brand,
|
|
||||||
};
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server injected values used to configure application.
|
|
||||||
*
|
|
||||||
* @singleton
|
|
||||||
*/
|
|
||||||
export const ServerContext = refreshServerContext();
|
|
||||||
|
|
||||||
export function docLink(path: string): string {
|
|
||||||
const { build, versionSubdomain } = ServerContext;
|
|
||||||
|
|
||||||
// Default case or beta build which should always point to latest
|
|
||||||
if (build) {
|
|
||||||
return new URL(path, "https://goauthentik.io").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new URL(path, `https://${versionSubdomain}.goauthentik.io`).toString();
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
|
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
|
||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
|
|
||||||
@ -22,14 +22,11 @@ export class WebsocketClient {
|
|||||||
|
|
||||||
connect(): void {
|
connect(): void {
|
||||||
if (navigator.webdriver) return;
|
if (navigator.webdriver) return;
|
||||||
|
const apiURL = new URL(globalAK().api.base);
|
||||||
const apiURL = new URL(ServerContext.baseURL);
|
const wsUrl = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
|
||||||
|
this.messageSocket = new WebSocket(wsUrl);
|
||||||
const wsURL = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
|
|
||||||
|
|
||||||
this.messageSocket = new WebSocket(wsURL);
|
|
||||||
this.messageSocket.addEventListener("open", () => {
|
this.messageSocket.addEventListener("open", () => {
|
||||||
console.debug(`authentik/ws: connected to ${wsURL}`);
|
console.debug(`authentik/ws: connected to ${wsUrl}`);
|
||||||
this.retryDelay = 200;
|
this.retryDelay = 200;
|
||||||
});
|
});
|
||||||
this.messageSocket.addEventListener("close", (e) => {
|
this.messageSocket.addEventListener("close", (e) => {
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
EVENT_API_DRAWER_TOGGLE,
|
EVENT_API_DRAWER_TOGGLE,
|
||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
|
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -146,7 +146,7 @@ export class NavigationButtons extends AKElement {
|
|||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-plain"
|
class="pf-c-button pf-m-plain"
|
||||||
type="button"
|
type="button"
|
||||||
href="${ServerContext.baseURL}if/user/#/settings"
|
href="${globalAK().api.base}if/user/#/settings"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Settings")}>
|
<pf-tooltip position="top" content=${msg("Settings")}>
|
||||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||||
@ -200,7 +200,7 @@ export class NavigationButtons extends AKElement {
|
|||||||
${this.renderSettings()}
|
${this.renderSettings()}
|
||||||
<div class="pf-c-page__header-tools-item">
|
<div class="pf-c-page__header-tools-item">
|
||||||
<a
|
<a
|
||||||
href="${ServerContext.baseURL}flows/-/default/invalidation/"
|
href="${globalAK().api.base}flows/-/default/invalidation/"
|
||||||
class="pf-c-button pf-m-plain"
|
class="pf-c-button pf-m-plain"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Sign out")}>
|
<pf-tooltip position="top" content=${msg("Sign out")}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import {
|
import {
|
||||||
StyleSheetInit,
|
StyleSheetInit,
|
||||||
StyleSheetParent,
|
StyleSheetParent,
|
||||||
@ -82,7 +82,7 @@ export class AKElement extends LitElement implements ThemedElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const { brand } = ServerContext;
|
const { brand } = globalAK();
|
||||||
|
|
||||||
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
|
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
|
||||||
this.activeTheme = resolveUITheme(brand?.uiTheme);
|
this.activeTheme = resolveUITheme(brand?.uiTheme);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { ThemedElement } from "@goauthentik/common/theme";
|
import { ThemedElement } from "@goauthentik/common/theme";
|
||||||
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
|
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
|
||||||
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
|
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
|
||||||
@ -23,8 +23,8 @@ export class ConfigContextController implements ReactiveController {
|
|||||||
initialValue: undefined,
|
initialValue: undefined,
|
||||||
});
|
});
|
||||||
// Pre-hydrate from template-embedded config
|
// Pre-hydrate from template-embedded config
|
||||||
this.context.setValue(ServerContext.config);
|
this.context.setValue(globalAK().config);
|
||||||
this.host.config = ServerContext.config;
|
this.host.config = globalAK().config;
|
||||||
this.fetch = this.fetch.bind(this);
|
this.fetch = this.fetch.bind(this);
|
||||||
this.fetch();
|
this.fetch();
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,9 @@ import {
|
|||||||
EVENT_WS_MESSAGE,
|
EVENT_WS_MESSAGE,
|
||||||
TITLE_DEFAULT,
|
TITLE_DEFAULT,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { getConfigForUser } from "@goauthentik/common/ui/config";
|
import { UIConfig, UserDisplay, getConfigForUser } from "@goauthentik/common/ui/config";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { UIConfig, UserDisplay } from "@goauthentik/common/ui/config";
|
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import "@goauthentik/components/ak-nav-buttons";
|
import "@goauthentik/components/ak-nav-buttons";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -405,7 +404,7 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
|
|||||||
<ak-nav-buttons .uiConfig=${this.uiConfig} .me=${this.session}>
|
<ak-nav-buttons .uiConfig=${this.uiConfig} .me=${this.session}>
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
||||||
href="${ServerContext.baseURL}if/user/"
|
href="${globalAK().api.base}if/user/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("User interface")}
|
${msg("User interface")}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
|
|
||||||
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
|
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
|
||||||
import { AkLocale } from "./types";
|
import { AkLocale } from "./types";
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ export function autoDetectLanguage(userReq = TOMBSTONE, brandReq = TOMBSTONE): s
|
|||||||
userReq,
|
userReq,
|
||||||
window.navigator?.language ?? TOMBSTONE,
|
window.navigator?.language ?? TOMBSTONE,
|
||||||
brandReq,
|
brandReq,
|
||||||
document.documentElement.getAttribute("lang") ?? TOMBSTONE,
|
globalAK()?.locale ?? TOMBSTONE,
|
||||||
DEFAULT_LOCALE,
|
DEFAULT_LOCALE,
|
||||||
].filter(isLocaleCandidate);
|
].filter(isLocaleCandidate);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
|
|||||||
: "pf-m-gold"}"
|
: "pf-m-gold"}"
|
||||||
>
|
>
|
||||||
${message}
|
${message}
|
||||||
<a href="${ServerContext.baseURL}if/admin/#/enterprise/licenses"
|
<a href="${globalAK().api.base}if/admin/#/enterprise/licenses"
|
||||||
>${msg("Click here for more info.")}</a
|
>${msg("Click here for more info.")}</a
|
||||||
>
|
>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ export class APIDrawer extends AKElement {
|
|||||||
<h1 class="pf-c-notification-drawer__header-title">
|
<h1 class="pf-c-notification-drawer__header-title">
|
||||||
${msg("API Requests")}
|
${msg("API Requests")}
|
||||||
</h1>
|
</h1>
|
||||||
<a href="${ServerContext.baseURL}api/v3/" target="_blank"
|
<a href="${globalAK().api.base}api/v3/" target="_blank"
|
||||||
>${msg("Open API Browser")}</a
|
>${msg("Open API Browser")}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -99,7 +99,7 @@ export class NotificationDrawer extends AKElement {
|
|||||||
html`
|
html`
|
||||||
<a
|
<a
|
||||||
class="pf-c-dropdown__toggle pf-m-plain"
|
class="pf-c-dropdown__toggle pf-m-plain"
|
||||||
href="${ServerContext.baseURL}if/admin/#/events/log/${item.event?.pk}"
|
href="${globalAK().api.base}if/admin/#/events/log/${item.event?.pk}"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Show details")}>
|
<pf-tooltip position="top" content=${msg("Show details")}>
|
||||||
<i class="fas fa-share-square"></i>
|
<i class="fas fa-share-square"></i>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
|
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||||
@ -45,7 +45,7 @@ export class SidebarVersion extends WithLicenseSummary(WithVersion(AKElement)) {
|
|||||||
if (!this.version || !this.licenseSummary) {
|
if (!this.version || !this.licenseSummary) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||||
product += ` ${msg("Enterprise")}`;
|
product += ` ${msg("Enterprise")}`;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import {
|
|||||||
EVENT_FLOW_INSPECTOR_TOGGLE,
|
EVENT_FLOW_INSPECTOR_TOGGLE,
|
||||||
TITLE_DEFAULT,
|
TITLE_DEFAULT,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { tryInitializeSentry } from "@goauthentik/common/sentry";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { Interface } from "@goauthentik/elements/Interface";
|
import { Interface } from "@goauthentik/elements/Interface";
|
||||||
@ -237,12 +237,10 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
tryInitializeSentry(ServerContext.config);
|
configureSentry();
|
||||||
|
|
||||||
if (this.config?.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
if (this.config?.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||||
this.inspectorAvailable = true;
|
this.inspectorAvailable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
const challenge = await new FlowsApi(DEFAULT_CONFIG).flowsExecutorGet({
|
const challenge = await new FlowsApi(DEFAULT_CONFIG).flowsExecutorGet({
|
||||||
@ -483,8 +481,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLayout(): string {
|
getLayout(): string {
|
||||||
const prefilledFlow = ServerContext.flowLayout || FlowLayoutEnum.Stacked;
|
const prefilledFlow = globalAK()?.flow?.layout || FlowLayoutEnum.Stacked;
|
||||||
|
|
||||||
if (this.challenge) {
|
if (this.challenge) {
|
||||||
return this.challenge?.flowInfo?.layout || prefilledFlow;
|
return this.challenge?.flowInfo?.layout || prefilledFlow;
|
||||||
}
|
}
|
||||||
@ -524,7 +521,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
<img
|
<img
|
||||||
src="${themeImage(
|
src="${themeImage(
|
||||||
this.brand?.brandingLogo ??
|
this.brand?.brandingLogo ??
|
||||||
ServerContext.brand.brandingLogo ??
|
globalAK()?.brand.brandingLogo ??
|
||||||
DefaultBrand.brandingLogo,
|
DefaultBrand.brandingLogo,
|
||||||
)}"
|
)}"
|
||||||
alt="${msg("authentik Logo")}"
|
alt="${msg("authentik Logo")}"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/flow/FormStatic";
|
import "@goauthentik/flow/FormStatic";
|
||||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ export class SessionEnd extends BaseStage<SessionEndChallenge, unknown> {
|
|||||||
str`You've logged out of ${this.challenge.applicationName}. You can go back to the overview to launch another application, or log out of your authentik account.`,
|
str`You've logged out of ${this.challenge.applicationName}. You can go back to the overview to launch another application, or log out of your authentik account.`,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<a href="${ServerContext.baseURL}" class="pf-c-button pf-m-primary">
|
<a href="${globalAK().api.base}" class="pf-c-button pf-m-primary">
|
||||||
${msg("Go back to overview")}
|
${msg("Go back to overview")}
|
||||||
</a>
|
</a>
|
||||||
${this.challenge.invalidationFlowUrl
|
${this.challenge.invalidationFlowUrl
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { PFSize } from "@goauthentik/common/enums.js";
|
import { PFSize } from "@goauthentik/common/enums.js";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { truncateWords } from "@goauthentik/common/utils";
|
import { truncateWords } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/AppIcon";
|
import "@goauthentik/elements/AppIcon";
|
||||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||||
@ -82,7 +82,8 @@ export class LibraryApplication extends AKElement {
|
|||||||
? html`
|
? html`
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
||||||
href="${ServerContext.baseURL}if/admin/#/core/applications/${application?.slug}"
|
href="${globalAK().api
|
||||||
|
.base}if/admin/#/core/applications/${application?.slug}"
|
||||||
>
|
>
|
||||||
<i class="fas fa-edit"></i> ${msg("Edit")}
|
<i class="fas fa-edit"></i> ${msg("Edit")}
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerContext, docLink } from "@goauthentik/common/server-context";
|
import { docLink, globalAK } from "@goauthentik/common/global";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export class LibraryPageApplicationEmptyList extends AKElement {
|
|||||||
<a
|
<a
|
||||||
aria-disabled="false"
|
aria-disabled="false"
|
||||||
class="cta pf-c-button pf-m-secondary"
|
class="cta pf-c-button pf-m-secondary"
|
||||||
href="${ServerContext.baseURL}if/admin/${href}"
|
href="${globalAK().api.base}if/admin/${href}"
|
||||||
>${msg("Create a new application")}</a
|
>${msg("Create a new application")}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,8 +4,8 @@ import {
|
|||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
EVENT_WS_MESSAGE,
|
EVENT_WS_MESSAGE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { UIConfig, getConfigForUser } from "@goauthentik/common/ui/config";
|
import { UIConfig, getConfigForUser } from "@goauthentik/common/ui/config";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
@ -170,14 +170,14 @@ class UserInterfacePresentation extends AKElement {
|
|||||||
|
|
||||||
return html`<a
|
return html`<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
||||||
href="${ServerContext.baseURL}if/admin/"
|
href="${globalAK().api.base}if/admin/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("Admin interface")}
|
${msg("Admin interface")}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none-on-md pf-u-display-block"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none-on-md pf-u-display-block"
|
||||||
href="${ServerContext.baseURL}if/admin/"
|
href="${globalAK().api.base}if/admin/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("Admin")}
|
${msg("Admin")}
|
||||||
@ -284,9 +284,7 @@ export class UserInterface extends AuthenticatedInterface {
|
|||||||
super();
|
super();
|
||||||
this.ws = new WebsocketClient();
|
this.ws = new WebsocketClient();
|
||||||
this.fetchConfigurationDetails();
|
this.fetchConfigurationDetails();
|
||||||
|
configureSentry(true);
|
||||||
tryInitializeSentry(ServerContext.config);
|
|
||||||
|
|
||||||
this.toggleNotificationDrawer = this.toggleNotificationDrawer.bind(this);
|
this.toggleNotificationDrawer = this.toggleNotificationDrawer.bind(this);
|
||||||
this.toggleApiDrawer = this.toggleApiDrawer.bind(this);
|
this.toggleApiDrawer = this.toggleApiDrawer.bind(this);
|
||||||
this.fetchConfigurationDetails = this.fetchConfigurationDetails.bind(this);
|
this.fetchConfigurationDetails = this.fetchConfigurationDetails.bind(this);
|
||||||
@ -327,8 +325,6 @@ export class UserInterface extends AuthenticatedInterface {
|
|||||||
this.me = session;
|
this.me = session;
|
||||||
this.uiConfig = getConfigForUser(session.user);
|
this.uiConfig = getConfigForUser(session.user);
|
||||||
|
|
||||||
setSentryPII(session.user);
|
|
||||||
|
|
||||||
new EventsApi(DEFAULT_CONFIG)
|
new EventsApi(DEFAULT_CONFIG)
|
||||||
.eventsNotificationsList({
|
.eventsNotificationsList({
|
||||||
seen: false,
|
seen: false,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AndNext } from "@goauthentik/common/api/config";
|
import { AndNext } from "@goauthentik/common/api/config";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -32,7 +32,7 @@ export class UserSettingsPassword extends AKElement {
|
|||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<a
|
<a
|
||||||
href="${ifDefined(this.configureUrl)}${AndNext(
|
href="${ifDefined(this.configureUrl)}${AndNext(
|
||||||
`${ServerContext.baseURL}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
|
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
|
||||||
)}"
|
)}"
|
||||||
class="pf-c-button pf-m-primary"
|
class="pf-c-button pf-m-primary"
|
||||||
>
|
>
|
||||||
|
@ -5,8 +5,8 @@ import {
|
|||||||
parseAPIResponseError,
|
parseAPIResponseError,
|
||||||
pluckErrorDetail,
|
pluckErrorDetail,
|
||||||
} from "@goauthentik/common/errors/network";
|
} from "@goauthentik/common/errors/network";
|
||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
|
||||||
import { refreshMe } from "@goauthentik/common/users";
|
import { refreshMe } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -181,7 +181,7 @@ export class UserSettingsFlowExecutor
|
|||||||
);
|
);
|
||||||
return html`
|
return html`
|
||||||
<a
|
<a
|
||||||
href="${ServerContext.baseURL}if/flow/${this.flowSlug}/"
|
href="${globalAK().api.base}if/flow/${this.flowSlug}/"
|
||||||
class="pf-c-button pf-m-primary"
|
class="pf-c-button pf-m-primary"
|
||||||
>
|
>
|
||||||
${msg("Open settings")}
|
${msg("Open settings")}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
|||||||
${this.host.brand?.flowUnenrollment
|
${this.host.brand?.flowUnenrollment
|
||||||
? html` <a
|
? html` <a
|
||||||
class="pf-c-button pf-m-danger"
|
class="pf-c-button pf-m-danger"
|
||||||
href="${ServerContext.baseURL}if/flow/${this.host.brand
|
href="${globalAK().api.base}if/flow/${this.host.brand
|
||||||
.flowUnenrollment}/"
|
.flowUnenrollment}/"
|
||||||
>
|
>
|
||||||
${msg("Delete account")}
|
${msg("Delete account")}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { deviceTypeName } from "@goauthentik/common/labels";
|
import { deviceTypeName } from "@goauthentik/common/labels";
|
||||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
||||||
import { ServerContext } from "@goauthentik/common/server-context";
|
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
import "@goauthentik/elements/buttons/ModalButton";
|
import "@goauthentik/elements/buttons/ModalButton";
|
||||||
@ -74,7 +74,7 @@ export class MFADevicesPage extends Table<Device> {
|
|||||||
return html`<li>
|
return html`<li>
|
||||||
<a
|
<a
|
||||||
href="${ifDefined(stage.configureUrl)}${AndNext(
|
href="${ifDefined(stage.configureUrl)}${AndNext(
|
||||||
`${ServerContext.baseURL}if/user/#/settings;${JSON.stringify({
|
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({
|
||||||
page: "page-mfa",
|
page: "page-mfa",
|
||||||
})}`,
|
})}`,
|
||||||
)}"
|
)}"
|
||||||
|
Reference in New Issue
Block a user