Compare commits

..

1 Commits

Author SHA1 Message Date
971b9e6bca docusaurus-config: v1.0.6 2025-05-03 02:38:03 +02:00
39 changed files with 241 additions and 355 deletions

View File

@ -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 = {

View File

@ -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)

View File

@ -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",

View File

@ -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": {

View File

@ -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) => {

View File

@ -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/");
} }
} }

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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({

View File

@ -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({

View File

@ -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({

View File

@ -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;
}); });
} }

View File

@ -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
View 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}`;
}

View File

@ -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;
} }

View File

@ -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();
}

View File

@ -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) => {

View File

@ -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")}>

View File

@ -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);

View File

@ -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();
} }

View File

@ -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")}

View File

@ -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);

View File

@ -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>`;

View File

@ -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>

View File

@ -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>

View File

@ -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")}`;
} }

View File

@ -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")}"

View File

@ -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

View File

@ -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>&nbsp;${msg("Edit")} <i class="fas fa-edit"></i>&nbsp;${msg("Edit")}
</a> </a>

View File

@ -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>

View File

@ -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,

View File

@ -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"
> >

View File

@ -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")}

View File

@ -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")}

View File

@ -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",
})}`, })}`,
)}" )}"