Compare commits
	
		
			1 Commits
		
	
	
		
			providers/
			...
			static-con
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 86c1d60093 | 
@ -1,6 +1,6 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { VERSION } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig, ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import "@goauthentik/elements/EmptyState";
 | 
			
		||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
 | 
			
		||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
 | 
			
		||||
@ -33,7 +33,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
 | 
			
		||||
        const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
 | 
			
		||||
        const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
 | 
			
		||||
        let build: string | TemplateResult = msg("Release");
 | 
			
		||||
        if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
 | 
			
		||||
        if (ServerConfig.capabilities.includes(CapabilitiesEnum.CanDebug)) {
 | 
			
		||||
            build = msg("Development");
 | 
			
		||||
        } else if (version.buildHash !== "") {
 | 
			
		||||
            build = html`<a
 | 
			
		||||
@ -58,7 +58,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    renderModal() {
 | 
			
		||||
        let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
 | 
			
		||||
        let product = BrandConfig.brandingTitle || DefaultBrand.brandingTitle;
 | 
			
		||||
        if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
 | 
			
		||||
            product += ` ${msg("Enterprise")}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,8 @@ import {
 | 
			
		||||
    GroupMatchingModeToLabel,
 | 
			
		||||
    UserMatchingModeToLabel,
 | 
			
		||||
} from "@goauthentik/admin/sources/oauth/utils";
 | 
			
		||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-switch-input";
 | 
			
		||||
import "@goauthentik/components/ak-text-input";
 | 
			
		||||
@ -61,8 +62,7 @@ export class KerberosSourceForm extends WithCapabilitiesConfig(BaseSourceForm<Ke
 | 
			
		||||
                kerberosSourceRequest: data as unknown as KerberosSourceRequest,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        const c = await config();
 | 
			
		||||
        if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
        if (ServerConfig.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
            const icon = this.getFormFiles()["icon"];
 | 
			
		||||
            if (icon || this.clearIcon) {
 | 
			
		||||
                await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,8 @@ import {
 | 
			
		||||
    GroupMatchingModeToLabel,
 | 
			
		||||
    UserMatchingModeToLabel,
 | 
			
		||||
} from "@goauthentik/admin/sources/oauth/utils";
 | 
			
		||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
@ -71,8 +72,7 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
 | 
			
		||||
                oAuthSourceRequest: data as unknown as OAuthSourceRequest,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        const c = await config();
 | 
			
		||||
        if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
        if (ServerConfig.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
            const icon = this.getFormFiles()["icon"];
 | 
			
		||||
            if (icon || this.clearIcon) {
 | 
			
		||||
                await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,8 @@ import {
 | 
			
		||||
    GroupMatchingModeToLabel,
 | 
			
		||||
    UserMatchingModeToLabel,
 | 
			
		||||
} from "@goauthentik/admin/sources/oauth/utils";
 | 
			
		||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import {
 | 
			
		||||
    CapabilitiesEnum,
 | 
			
		||||
@ -62,8 +63,7 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
 | 
			
		||||
                sAMLSourceRequest: data,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        const c = await config();
 | 
			
		||||
        if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
        if (ServerConfig.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
 | 
			
		||||
            const icon = this.getFormFiles()["icon"];
 | 
			
		||||
            if (icon || this.clearIcon) {
 | 
			
		||||
                await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import "@goauthentik/components/ak-text-input";
 | 
			
		||||
import { Form } from "@goauthentik/elements/forms/Form";
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ export class UserImpersonateForm extends Form<ImpersonationRequest> {
 | 
			
		||||
                impersonationRequest: data,
 | 
			
		||||
            })
 | 
			
		||||
            .then(() => {
 | 
			
		||||
                window.location.href = globalAK().api.base;
 | 
			
		||||
                window.location.href = APIConfig.base;
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,79 +3,40 @@ import {
 | 
			
		||||
    EventMiddleware,
 | 
			
		||||
    LoggingMiddleware,
 | 
			
		||||
} from "@goauthentik/common/api/middleware";
 | 
			
		||||
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { VERSION } from "@goauthentik/common/constants";
 | 
			
		||||
import { APIConfig, BrandConfig } from "@goauthentik/common/global";
 | 
			
		||||
 | 
			
		||||
import { Config, Configuration, CoreApi, CurrentBrand, RootApi } from "@goauthentik/api";
 | 
			
		||||
import { Configuration as ApiConfiguration } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
 | 
			
		||||
export function config(): Promise<Config> {
 | 
			
		||||
    if (!globalConfigPromise) {
 | 
			
		||||
        globalConfigPromise = new RootApi(DEFAULT_CONFIG).rootConfigRetrieve();
 | 
			
		||||
    }
 | 
			
		||||
    return globalConfigPromise;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Extract the content of a meta tag by name.
 | 
			
		||||
 *
 | 
			
		||||
 * @todo Can we memoize this?
 | 
			
		||||
 */
 | 
			
		||||
function extractMetaContent(name: string): string {
 | 
			
		||||
    const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${name}]`);
 | 
			
		||||
 | 
			
		||||
export function brandSetFavicon(brand: CurrentBrand) {
 | 
			
		||||
    /**
 | 
			
		||||
     *  <link rel="icon" href="/static/dist/assets/icons/icon.png">
 | 
			
		||||
     *  <link rel="shortcut icon" href="/static/dist/assets/icons/icon.png">
 | 
			
		||||
     */
 | 
			
		||||
    const rels = ["icon", "shortcut icon"];
 | 
			
		||||
    rels.forEach((rel) => {
 | 
			
		||||
        let relIcon = document.head.querySelector<HTMLLinkElement>(`link[rel='${rel}']`);
 | 
			
		||||
        if (!relIcon) {
 | 
			
		||||
            relIcon = document.createElement("link");
 | 
			
		||||
            relIcon.rel = rel;
 | 
			
		||||
            document.getElementsByTagName("head")[0].appendChild(relIcon);
 | 
			
		||||
        }
 | 
			
		||||
        relIcon.href = brand.brandingFavicon;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function brandSetLocale(brand: CurrentBrand) {
 | 
			
		||||
    if (brand.defaultLocale === "") {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    console.debug("authentik/locale: setting locale from brand default");
 | 
			
		||||
    window.dispatchEvent(
 | 
			
		||||
        new CustomEvent(EVENT_LOCALE_REQUEST, {
 | 
			
		||||
            composed: true,
 | 
			
		||||
            bubbles: true,
 | 
			
		||||
            detail: { locale: brand.defaultLocale },
 | 
			
		||||
        }),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
    const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
 | 
			
		||||
    if (!metaEl) return "";
 | 
			
		||||
 | 
			
		||||
    return metaEl.content;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_CONFIG = new Configuration({
 | 
			
		||||
    basePath: `${globalAK().api.base}api/v3`,
 | 
			
		||||
/**
 | 
			
		||||
 * Default API Configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * @todo This is a frequent source of duplication when working with the API.
 | 
			
		||||
 * We should consider moving this to a more central location.
 | 
			
		||||
 */
 | 
			
		||||
export const DEFAULT_CONFIG = new ApiConfiguration({
 | 
			
		||||
    basePath: `${APIConfig.base}api/v3`,
 | 
			
		||||
    headers: {
 | 
			
		||||
        "sentry-trace": getMetaContent("sentry-trace"),
 | 
			
		||||
        "sentry-trace": extractMetaContent("sentry-trace"),
 | 
			
		||||
    },
 | 
			
		||||
    middleware: [
 | 
			
		||||
        // ---
 | 
			
		||||
        new CSRFMiddleware(),
 | 
			
		||||
        new EventMiddleware(),
 | 
			
		||||
        new LoggingMiddleware(globalAK().brand),
 | 
			
		||||
        new LoggingMiddleware(BrandConfig),
 | 
			
		||||
    ],
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,59 +1,142 @@
 | 
			
		||||
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
export interface GlobalAuthentik {
 | 
			
		||||
    _converted?: boolean;
 | 
			
		||||
export interface APIConfig {
 | 
			
		||||
    /**
 | 
			
		||||
     * Absolute base path to the API.
 | 
			
		||||
     */
 | 
			
		||||
    base: string;
 | 
			
		||||
    /**
 | 
			
		||||
     * Relative base path to the API.
 | 
			
		||||
     */
 | 
			
		||||
    relBase: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface FlowConfig {
 | 
			
		||||
    /**
 | 
			
		||||
     * The current flow ID.
 | 
			
		||||
     */
 | 
			
		||||
    layout: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SerializedClientState {
 | 
			
		||||
    /**
 | 
			
		||||
     * The BCP47 language tag.
 | 
			
		||||
     */
 | 
			
		||||
    locale?: string;
 | 
			
		||||
    flow?: {
 | 
			
		||||
        layout: string;
 | 
			
		||||
    };
 | 
			
		||||
    config: Config;
 | 
			
		||||
    brand: CurrentBrand;
 | 
			
		||||
    /**
 | 
			
		||||
     * Current flow state.
 | 
			
		||||
     */
 | 
			
		||||
    flow?: FlowConfig;
 | 
			
		||||
    /**
 | 
			
		||||
     * Server configuration.
 | 
			
		||||
     */
 | 
			
		||||
    config: unknown;
 | 
			
		||||
    /**
 | 
			
		||||
     * Branding information.
 | 
			
		||||
     */
 | 
			
		||||
    brand: unknown;
 | 
			
		||||
    /**
 | 
			
		||||
     * The major and minor components of the current version.
 | 
			
		||||
     */
 | 
			
		||||
    versionFamily: string;
 | 
			
		||||
    /**
 | 
			
		||||
     * A subdomain compatible SemVer.
 | 
			
		||||
     */
 | 
			
		||||
    versionSubdomain: string;
 | 
			
		||||
    /**
 | 
			
		||||
     * The current build hash.
 | 
			
		||||
     */
 | 
			
		||||
    build: string;
 | 
			
		||||
    api: {
 | 
			
		||||
        base: string;
 | 
			
		||||
        relBase: string;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The API configuration.
 | 
			
		||||
     */
 | 
			
		||||
    api: APIConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ClientConfigRealm<T> = T & {
 | 
			
		||||
    readonly authentik: Readonly<SerializedClientState>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function isClientConfigRealm<T>(namespace: object): namespace is ClientConfigRealm<T> {
 | 
			
		||||
    return typeof namespace === "object" && "authentik" in namespace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The current locale as defined by the server.
 | 
			
		||||
 *
 | 
			
		||||
 * @format BCP47
 | 
			
		||||
 */
 | 
			
		||||
export let ServerLocale = "";
 | 
			
		||||
 | 
			
		||||
export let FlowConfig: FlowConfig | undefined;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The current build hash.
 | 
			
		||||
 */
 | 
			
		||||
export let BuildHash = "";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The major and minor components of the SemVer.
 | 
			
		||||
 */
 | 
			
		||||
export let VersionFamily = "";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A subdomain compatible SemVer.
 | 
			
		||||
 */
 | 
			
		||||
export let VersionSubdomain = "";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The parsed API configuration extracted from the global scope.
 | 
			
		||||
 */
 | 
			
		||||
export let APIConfig: Readonly<APIConfig>;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The parsed server configuration extracted from the global scope.
 | 
			
		||||
 */
 | 
			
		||||
export let ServerConfig: Readonly<Config>;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The parsed brand configuration extracted from the global scope.
 | 
			
		||||
 */
 | 
			
		||||
export let BrandConfig: Readonly<CurrentBrand>;
 | 
			
		||||
 | 
			
		||||
if (!isClientConfigRealm(self)) {
 | 
			
		||||
    const apiOrigin = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
 | 
			
		||||
 | 
			
		||||
    APIConfig = {
 | 
			
		||||
        base: apiOrigin.toString(),
 | 
			
		||||
        relBase: apiOrigin.pathname,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BrandConfig = CurrentBrandFromJSON({
 | 
			
		||||
        ui_footer_links: [],
 | 
			
		||||
    });
 | 
			
		||||
} else {
 | 
			
		||||
    ServerLocale = self.authentik.locale || "";
 | 
			
		||||
    FlowConfig = self.authentik.flow;
 | 
			
		||||
 | 
			
		||||
    BuildHash = self.authentik.build;
 | 
			
		||||
 | 
			
		||||
    VersionFamily = self.authentik.versionFamily;
 | 
			
		||||
    VersionSubdomain = self.authentik.versionSubdomain;
 | 
			
		||||
 | 
			
		||||
    ServerConfig = ConfigFromJSON(self.authentik.config);
 | 
			
		||||
    BrandConfig = CurrentBrandFromJSON(self.authentik.brand);
 | 
			
		||||
    APIConfig = self.authentik.api;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface AuthentikWindow {
 | 
			
		||||
    authentik: GlobalAuthentik;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Generate a link to the documentation.
 | 
			
		||||
 */
 | 
			
		||||
export function docLink(documentationPath: string): string {
 | 
			
		||||
    const origin =
 | 
			
		||||
        // Default case or beta build which should always point to latest
 | 
			
		||||
        BuildHash || !VersionSubdomain
 | 
			
		||||
            ? "https://goauthentik.io"
 | 
			
		||||
            : `https://${VersionSubdomain}.goauthentik.io`;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
    const docsURL = new URL(documentationPath, origin);
 | 
			
		||||
 | 
			
		||||
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}`;
 | 
			
		||||
    return docsURL.toString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,98 +1,106 @@
 | 
			
		||||
import { config } from "@goauthentik/common/api/config";
 | 
			
		||||
import { VERSION } from "@goauthentik/common/constants";
 | 
			
		||||
import { SentryIgnoredError } from "@goauthentik/common/errors";
 | 
			
		||||
import { ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
import {
 | 
			
		||||
    ErrorEvent,
 | 
			
		||||
    EventHint,
 | 
			
		||||
    browserTracingIntegration,
 | 
			
		||||
    init,
 | 
			
		||||
    setTag,
 | 
			
		||||
    setUser,
 | 
			
		||||
} from "@sentry/browser";
 | 
			
		||||
import { browserTracingIntegration, init, setTag, setUser } from "@sentry/browser";
 | 
			
		||||
 | 
			
		||||
import { CapabilitiesEnum, Config, ResponseError } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A generic error that can be thrown without triggering Sentry's reporting.
 | 
			
		||||
 */
 | 
			
		||||
export class SentryIgnoredError extends Error {}
 | 
			
		||||
import { CapabilitiesEnum, ResponseError } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
export const TAG_SENTRY_COMPONENT = "authentik.component";
 | 
			
		||||
export const TAG_SENTRY_CAPABILITIES = "authentik.capabilities";
 | 
			
		||||
 | 
			
		||||
export async function configureSentry(canDoPpi = false): Promise<Config> {
 | 
			
		||||
    const cfg = await config();
 | 
			
		||||
/**
 | 
			
		||||
 * Configure Sentry with the given configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * @param canSendPII Whether the user can send personally identifiable information.
 | 
			
		||||
 */
 | 
			
		||||
export async function configureSentry(canSendPII?: boolean): Promise<void> {
 | 
			
		||||
    if (!ServerConfig.errorReporting.enabled) return;
 | 
			
		||||
    const { capabilities, errorReporting } = ServerConfig;
 | 
			
		||||
 | 
			
		||||
    if (cfg.errorReporting.enabled) {
 | 
			
		||||
        init({
 | 
			
		||||
            dsn: cfg.errorReporting.sentryDsn,
 | 
			
		||||
            ignoreErrors: [
 | 
			
		||||
                /network/gi,
 | 
			
		||||
                /fetch/gi,
 | 
			
		||||
                /module/gi,
 | 
			
		||||
                // Error on edge on ios,
 | 
			
		||||
                // https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
 | 
			
		||||
                /instantSearchSDKJSBridgeClearHighlight/gi,
 | 
			
		||||
                // Seems to be an issue in Safari and Firefox
 | 
			
		||||
                /MutationObserver.observe/gi,
 | 
			
		||||
                /NS_ERROR_FAILURE/gi,
 | 
			
		||||
            ],
 | 
			
		||||
            release: `authentik@${VERSION}`,
 | 
			
		||||
            integrations: [
 | 
			
		||||
                browserTracingIntegration({
 | 
			
		||||
                    shouldCreateSpanForRequest: (url: string) => {
 | 
			
		||||
                        return url.startsWith(window.location.host);
 | 
			
		||||
                    },
 | 
			
		||||
                }),
 | 
			
		||||
            ],
 | 
			
		||||
            tracesSampleRate: cfg.errorReporting.tracesSampleRate,
 | 
			
		||||
            environment: cfg.errorReporting.environment,
 | 
			
		||||
            beforeSend: (
 | 
			
		||||
                event: ErrorEvent,
 | 
			
		||||
                hint: EventHint,
 | 
			
		||||
            ): ErrorEvent | PromiseLike<ErrorEvent | null> | null => {
 | 
			
		||||
                if (!hint) {
 | 
			
		||||
                    return event;
 | 
			
		||||
                }
 | 
			
		||||
                if (hint.originalException instanceof SentryIgnoredError) {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
                if (
 | 
			
		||||
                    hint.originalException instanceof ResponseError ||
 | 
			
		||||
                    hint.originalException instanceof DOMException
 | 
			
		||||
                ) {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
                return event;
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
        setTag(TAG_SENTRY_CAPABILITIES, cfg.capabilities.join(","));
 | 
			
		||||
        if (window.location.pathname.includes("if/")) {
 | 
			
		||||
            setTag(TAG_SENTRY_COMPONENT, `web/${currentInterface()}`);
 | 
			
		||||
        }
 | 
			
		||||
        if (cfg.capabilities.includes(CapabilitiesEnum.CanDebug)) {
 | 
			
		||||
            const Spotlight = await import("@spotlightjs/spotlight");
 | 
			
		||||
    init({
 | 
			
		||||
        dsn: errorReporting.sentryDsn,
 | 
			
		||||
        ignoreErrors: [
 | 
			
		||||
            /network/gi,
 | 
			
		||||
            /fetch/gi,
 | 
			
		||||
            /module/gi,
 | 
			
		||||
            // Error on edge on ios,
 | 
			
		||||
            // https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
 | 
			
		||||
            /instantSearchSDKJSBridgeClearHighlight/gi,
 | 
			
		||||
            // Seems to be an issue in Safari and Firefox
 | 
			
		||||
            /MutationObserver.observe/gi,
 | 
			
		||||
            /NS_ERROR_FAILURE/gi,
 | 
			
		||||
        ],
 | 
			
		||||
        release: `authentik@${VERSION}`,
 | 
			
		||||
        integrations: [
 | 
			
		||||
            browserTracingIntegration({
 | 
			
		||||
                shouldCreateSpanForRequest: (url: string) => {
 | 
			
		||||
                    return url.startsWith(window.location.host);
 | 
			
		||||
                },
 | 
			
		||||
            }),
 | 
			
		||||
        ],
 | 
			
		||||
        tracesSampleRate: errorReporting.tracesSampleRate,
 | 
			
		||||
        environment: errorReporting.environment,
 | 
			
		||||
        beforeSend: (event, hint) => {
 | 
			
		||||
            if (!hint) return event;
 | 
			
		||||
 | 
			
		||||
            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.");
 | 
			
		||||
            const { originalException } = hint;
 | 
			
		||||
 | 
			
		||||
            if (originalException instanceof SentryIgnoredError) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (originalException instanceof ResponseError) return null;
 | 
			
		||||
            if (originalException instanceof DOMException) return null;
 | 
			
		||||
 | 
			
		||||
            return event;
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    setTag(TAG_SENTRY_CAPABILITIES, capabilities.join(","));
 | 
			
		||||
 | 
			
		||||
    if (window.location.pathname.includes("if/")) {
 | 
			
		||||
        setTag(TAG_SENTRY_COMPONENT, `web/${currentInterface()}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
        // Retain this predicate order to allow ESBuild to tree-shake the import in production.
 | 
			
		||||
        process.env.NODE_ENV === "development" &&
 | 
			
		||||
        capabilities.includes(CapabilitiesEnum.CanDebug)
 | 
			
		||||
    ) {
 | 
			
		||||
        await import("@spotlightjs/spotlight")
 | 
			
		||||
            .then((Spotlight) => {
 | 
			
		||||
                return Spotlight.init({
 | 
			
		||||
                    injectImmediately: true,
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
            .catch((error) => {
 | 
			
		||||
                console.error("Failed to init Spotlight", error);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            console.debug("authentik/config: Sentry enabled.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (errorReporting.sendPii && canSendPII) {
 | 
			
		||||
        const session = await me().catch(() => null);
 | 
			
		||||
 | 
			
		||||
        if (session) {
 | 
			
		||||
            setUser({ email: session.user.email });
 | 
			
		||||
            console.debug("authentik/config: Sentry PII enabled.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return cfg;
 | 
			
		||||
 | 
			
		||||
    console.debug("authentik/config: Sentry enabled.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the interface name from URL
 | 
			
		||||
/**
 | 
			
		||||
 * Get the current interface from the URL.
 | 
			
		||||
 */
 | 
			
		||||
export function currentInterface(): string {
 | 
			
		||||
    const pathMatches = window.location.pathname.match(/.+if\/(\w+)\//);
 | 
			
		||||
    let currentInterface = "unknown";
 | 
			
		||||
 | 
			
		||||
    if (pathMatches && pathMatches.length >= 2) {
 | 
			
		||||
        currentInterface = pathMatches[1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return currentInterface.toLowerCase();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { MessageLevel } from "@goauthentik/common/messages";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
@ -22,7 +22,8 @@ export class WebsocketClient {
 | 
			
		||||
 | 
			
		||||
    connect(): void {
 | 
			
		||||
        if (navigator.webdriver) return;
 | 
			
		||||
        const apiURL = new URL(globalAK().api.base);
 | 
			
		||||
 | 
			
		||||
        const apiURL = new URL(APIConfig.base);
 | 
			
		||||
        const wsUrl = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
 | 
			
		||||
        this.messageSocket = new WebSocket(wsUrl);
 | 
			
		||||
        this.messageSocket.addEventListener("open", () => {
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import {
 | 
			
		||||
    EVENT_API_DRAWER_TOGGLE,
 | 
			
		||||
    EVENT_NOTIFICATION_DRAWER_TOGGLE,
 | 
			
		||||
} from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
@ -146,7 +146,7 @@ export class NavigationButtons extends AKElement {
 | 
			
		||||
            <a
 | 
			
		||||
                class="pf-c-button pf-m-plain"
 | 
			
		||||
                type="button"
 | 
			
		||||
                href="${globalAK().api.base}if/user/#/settings"
 | 
			
		||||
                href="${APIConfig.base}if/user/#/settings"
 | 
			
		||||
            >
 | 
			
		||||
                <pf-tooltip position="top" content=${msg("Settings")}>
 | 
			
		||||
                    <i class="fas fa-cog" aria-hidden="true"></i>
 | 
			
		||||
@ -194,7 +194,7 @@ export class NavigationButtons extends AKElement {
 | 
			
		||||
                ${this.renderSettings()}
 | 
			
		||||
                <div class="pf-c-page__header-tools-item">
 | 
			
		||||
                    <a
 | 
			
		||||
                        href="${globalAK().api.base}flows/-/default/invalidation/"
 | 
			
		||||
                        href="${APIConfig.base}flows/-/default/invalidation/"
 | 
			
		||||
                        class="pf-c-button pf-m-plain"
 | 
			
		||||
                    >
 | 
			
		||||
                        <pf-tooltip position="top" content=${msg("Sign out")}>
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { UIConfig } from "@goauthentik/common/ui/config";
 | 
			
		||||
import { adaptCSS } from "@goauthentik/common/utils";
 | 
			
		||||
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet";
 | 
			
		||||
@ -78,7 +78,7 @@ export class AKElement extends LitElement {
 | 
			
		||||
    async _initTheme(root: DocumentOrShadowRoot): Promise<void> {
 | 
			
		||||
        // Early activate theme based on media query to prevent light flash
 | 
			
		||||
        // when dark is preferred
 | 
			
		||||
        this._applyTheme(root, globalAK().brand.uiTheme);
 | 
			
		||||
        this._applyTheme(root, BrandConfig.uiTheme);
 | 
			
		||||
        this._applyTheme(root, await this.getTheme());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { ServerConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
 | 
			
		||||
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
 | 
			
		||||
 | 
			
		||||
@ -24,8 +24,8 @@ export class ConfigContextController implements ReactiveController {
 | 
			
		||||
            initialValue: undefined,
 | 
			
		||||
        });
 | 
			
		||||
        // Pre-hydrate from template-embedded config
 | 
			
		||||
        this.context.setValue(globalAK().config);
 | 
			
		||||
        this.host.config = globalAK().config;
 | 
			
		||||
        this.context.setValue(ServerConfig);
 | 
			
		||||
        this.host.config = ServerConfig;
 | 
			
		||||
        this.fetch = this.fetch.bind(this);
 | 
			
		||||
        this.fetch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import {
 | 
			
		||||
    EVENT_WS_MESSAGE,
 | 
			
		||||
    TITLE_DEFAULT,
 | 
			
		||||
} from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { currentInterface } from "@goauthentik/common/sentry";
 | 
			
		||||
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
@ -186,7 +186,7 @@ export class PageHeader extends WithBrandConfig(AKElement) {
 | 
			
		||||
                    <ak-nav-buttons .uiConfig=${this.uiConfig} .me=${this.me}>
 | 
			
		||||
                        <a
 | 
			
		||||
                            class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
 | 
			
		||||
                            href="${globalAK().api.base}if/user/"
 | 
			
		||||
                            href="${APIConfig.base}if/user/"
 | 
			
		||||
                            slot="extra"
 | 
			
		||||
                        >
 | 
			
		||||
                            ${msg("User interface")}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { ServerLocale } from "@goauthentik/common/global";
 | 
			
		||||
 | 
			
		||||
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
 | 
			
		||||
import { AkLocale } from "./types";
 | 
			
		||||
@ -51,7 +51,7 @@ export function autoDetectLanguage(userReq = TOMBSTONE, brandReq = TOMBSTONE): s
 | 
			
		||||
        userReq,
 | 
			
		||||
        window.navigator?.language ?? TOMBSTONE,
 | 
			
		||||
        brandReq,
 | 
			
		||||
        globalAK()?.locale ?? TOMBSTONE,
 | 
			
		||||
        ServerLocale ?? TOMBSTONE,
 | 
			
		||||
        DEFAULT_LOCALE,
 | 
			
		||||
    ].filter(isLocaleCandidate);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
 | 
			
		||||
                : "pf-m-gold"}"
 | 
			
		||||
        >
 | 
			
		||||
            ${message}
 | 
			
		||||
            <a href="${globalAK().api.base}if/admin/#/enterprise/licenses"
 | 
			
		||||
            <a href="${APIConfig.base}if/admin/#/enterprise/licenses"
 | 
			
		||||
                >${msg("Click here for more info.")}</a
 | 
			
		||||
            >
 | 
			
		||||
        </div>`;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { RequestInfo } from "@goauthentik/common/api/middleware";
 | 
			
		||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
 | 
			
		||||
@ -92,7 +92,7 @@ export class APIDrawer extends AKElement {
 | 
			
		||||
                        <h1 class="pf-c-notification-drawer__header-title">
 | 
			
		||||
                            ${msg("API Requests")}
 | 
			
		||||
                        </h1>
 | 
			
		||||
                        <a href="${globalAK().api.base}api/v3/" target="_blank"
 | 
			
		||||
                        <a href="${APIConfig.base}api/v3/" target="_blank"
 | 
			
		||||
                            >${msg("Open API Browser")}</a
 | 
			
		||||
                        >
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { actionToLabel } from "@goauthentik/common/labels";
 | 
			
		||||
import { MessageLevel } from "@goauthentik/common/messages";
 | 
			
		||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
 | 
			
		||||
@ -99,7 +99,7 @@ export class NotificationDrawer extends AKElement {
 | 
			
		||||
                html`
 | 
			
		||||
                    <a
 | 
			
		||||
                        class="pf-c-dropdown__toggle pf-m-plain"
 | 
			
		||||
                        href="${globalAK().api.base}if/admin/#/events/log/${item.event?.pk}"
 | 
			
		||||
                        href="${APIConfig.base}if/admin/#/events/log/${item.event?.pk}"
 | 
			
		||||
                    >
 | 
			
		||||
                        <pf-tooltip position="top" content=${msg("Show details")}>
 | 
			
		||||
                            <i class="fas fa-share-square"></i>
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/AdminInterface";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
 | 
			
		||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
 | 
			
		||||
import { WithVersion } from "@goauthentik/elements/Interface/versionProvider";
 | 
			
		||||
@ -45,7 +45,7 @@ export class SidebarVersion extends WithLicenseSummary(WithVersion(AKElement)) {
 | 
			
		||||
        if (!this.version || !this.licenseSummary) {
 | 
			
		||||
            return nothing;
 | 
			
		||||
        }
 | 
			
		||||
        let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
 | 
			
		||||
        let product = BrandConfig.brandingTitle || DefaultBrand.brandingTitle;
 | 
			
		||||
        if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
 | 
			
		||||
            product += ` ${msg("Enterprise")}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import {
 | 
			
		||||
    EVENT_FLOW_INSPECTOR_TOGGLE,
 | 
			
		||||
    TITLE_DEFAULT,
 | 
			
		||||
} from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig, FlowConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { configureSentry } from "@goauthentik/common/sentry";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import { WebsocketClient } from "@goauthentik/common/ws";
 | 
			
		||||
@ -201,7 +201,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getTheme(): Promise<UiThemeEnum> {
 | 
			
		||||
        return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
        return BrandConfig.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async submit(
 | 
			
		||||
@ -487,7 +487,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getLayout(): string {
 | 
			
		||||
        const prefilledFlow = globalAK()?.flow?.layout || FlowLayoutEnum.Stacked;
 | 
			
		||||
        const prefilledFlow = FlowConfig?.layout || FlowLayoutEnum.Stacked;
 | 
			
		||||
        if (this.challenge) {
 | 
			
		||||
            return this.challenge?.flowInfo?.layout || prefilledFlow;
 | 
			
		||||
        }
 | 
			
		||||
@ -528,7 +528,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
			
		||||
                                                    src="${themeImage(
 | 
			
		||||
                                                        first(
 | 
			
		||||
                                                            this.brand?.brandingLogo,
 | 
			
		||||
                                                            globalAK()?.brand.brandingLogo,
 | 
			
		||||
                                                            BrandConfig.brandingLogo,
 | 
			
		||||
                                                            DefaultBrand.brandingLogo,
 | 
			
		||||
                                                        ),
 | 
			
		||||
                                                    )}"
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import "@goauthentik/flow/FormStatic";
 | 
			
		||||
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.`,
 | 
			
		||||
                        )}
 | 
			
		||||
                    </p>
 | 
			
		||||
                    <a href="${globalAK().api.base}" class="pf-c-button pf-m-primary">
 | 
			
		||||
                    <a href="${APIConfig.base}" class="pf-c-button pf-m-primary">
 | 
			
		||||
                        ${msg("Go back to overview")}
 | 
			
		||||
                    </a>
 | 
			
		||||
                    ${this.challenge.invalidationFlowUrl
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { CSRFHeaderName } from "@goauthentik/common/api/middleware";
 | 
			
		||||
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { first, getCookie } from "@goauthentik/common/utils";
 | 
			
		||||
import { Interface } from "@goauthentik/elements/Interface";
 | 
			
		||||
import "@goauthentik/elements/ak-locale-context";
 | 
			
		||||
@ -61,7 +61,7 @@ export class APIBrowser extends Interface {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getTheme(): Promise<UiThemeEnum> {
 | 
			
		||||
        return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
        return BrandConfig.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render(): TemplateResult {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { BrandConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { Interface } from "@goauthentik/elements/Interface";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
@ -39,7 +39,7 @@ export class Loading extends Interface {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getTheme(): Promise<UiThemeEnum> {
 | 
			
		||||
        return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
        return BrandConfig.uiTheme || UiThemeEnum.Automatic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render(): TemplateResult {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { PFSize } from "@goauthentik/common/enums.js";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { truncateWords } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/AppIcon";
 | 
			
		||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
 | 
			
		||||
@ -82,8 +82,7 @@ export class LibraryApplication extends AKElement {
 | 
			
		||||
                ? html`
 | 
			
		||||
                      <a
 | 
			
		||||
                          class="pf-c-button pf-m-control pf-m-small pf-m-block"
 | 
			
		||||
                          href="${globalAK().api
 | 
			
		||||
                              .base}if/admin/#/core/applications/${application?.slug}"
 | 
			
		||||
                          href="${APIConfig.base}if/admin/#/core/applications/${application?.slug}"
 | 
			
		||||
                      >
 | 
			
		||||
                          <i class="fas fa-edit"></i> ${msg("Edit")}
 | 
			
		||||
                      </a>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { docLink, globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig, docLink } from "@goauthentik/common/global";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ export class LibraryPageApplicationEmptyList extends AKElement {
 | 
			
		||||
                <a
 | 
			
		||||
                    aria-disabled="false"
 | 
			
		||||
                    class="cta pf-c-button pf-m-secondary"
 | 
			
		||||
                    href="${globalAK().api.base}if/admin/${href}"
 | 
			
		||||
                    href="${APIConfig.base}if/admin/${href}"
 | 
			
		||||
                    >${msg("Create a new application")}</a
 | 
			
		||||
                >
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import {
 | 
			
		||||
    EVENT_NOTIFICATION_DRAWER_TOGGLE,
 | 
			
		||||
    EVENT_WS_MESSAGE,
 | 
			
		||||
} from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { configureSentry } from "@goauthentik/common/sentry";
 | 
			
		||||
import { UIConfig } from "@goauthentik/common/ui/config";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
@ -166,14 +166,14 @@ class UserInterfacePresentation extends AKElement {
 | 
			
		||||
 | 
			
		||||
        return html`<a
 | 
			
		||||
                class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
 | 
			
		||||
                href="${globalAK().api.base}if/admin/"
 | 
			
		||||
                href="${APIConfig.base}if/admin/"
 | 
			
		||||
                slot="extra"
 | 
			
		||||
            >
 | 
			
		||||
                ${msg("Admin interface")}
 | 
			
		||||
            </a>
 | 
			
		||||
            <a
 | 
			
		||||
                class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none-on-md pf-u-display-block"
 | 
			
		||||
                href="${globalAK().api.base}if/admin/"
 | 
			
		||||
                href="${APIConfig.base}if/admin/"
 | 
			
		||||
                slot="extra"
 | 
			
		||||
            >
 | 
			
		||||
                ${msg("Admin")}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { AndNext } from "@goauthentik/common/api/config";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
@ -32,7 +32,7 @@ export class UserSettingsPassword extends AKElement {
 | 
			
		||||
            <div class="pf-c-card__body">
 | 
			
		||||
                <a
 | 
			
		||||
                    href="${ifDefined(this.configureUrl)}${AndNext(
 | 
			
		||||
                        `${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
 | 
			
		||||
                        `${APIConfig.relBase}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
 | 
			
		||||
                    )}"
 | 
			
		||||
                    class="pf-c-button pf-m-primary"
 | 
			
		||||
                >
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ import {
 | 
			
		||||
    parseAPIResponseError,
 | 
			
		||||
    pluckErrorDetail,
 | 
			
		||||
} from "@goauthentik/common/errors/network";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { MessageLevel } from "@goauthentik/common/messages";
 | 
			
		||||
import { refreshMe } from "@goauthentik/common/users";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
@ -181,7 +181,7 @@ export class UserSettingsFlowExecutor
 | 
			
		||||
                );
 | 
			
		||||
                return html`
 | 
			
		||||
                    <a
 | 
			
		||||
                        href="${globalAK().api.base}if/flow/${this.flowSlug}/"
 | 
			
		||||
                        href="${APIConfig.base}if/flow/${this.flowSlug}/"
 | 
			
		||||
                        class="pf-c-button pf-m-primary"
 | 
			
		||||
                    >
 | 
			
		||||
                        ${msg("Open settings")}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
 | 
			
		||||
 | 
			
		||||
@ -51,8 +51,7 @@ export class UserSettingsPromptStage extends PromptStage {
 | 
			
		||||
                    ${this.host.brand?.flowUnenrollment
 | 
			
		||||
                        ? html` <a
 | 
			
		||||
                              class="pf-c-button pf-m-danger"
 | 
			
		||||
                              href="${globalAK().api.base}if/flow/${this.host.brand
 | 
			
		||||
                                  .flowUnenrollment}/"
 | 
			
		||||
                              href="${APIConfig.base}if/flow/${this.host.brand.flowUnenrollment}/"
 | 
			
		||||
                          >
 | 
			
		||||
                              ${msg("Delete account")}
 | 
			
		||||
                          </a>`
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { SentryIgnoredError } from "@goauthentik/common/errors";
 | 
			
		||||
import { APIConfig } from "@goauthentik/common/global";
 | 
			
		||||
import { deviceTypeName } from "@goauthentik/common/labels";
 | 
			
		||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
 | 
			
		||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
 | 
			
		||||
import "@goauthentik/elements/buttons/Dropdown";
 | 
			
		||||
import "@goauthentik/elements/buttons/ModalButton";
 | 
			
		||||
@ -74,7 +74,7 @@ export class MFADevicesPage extends Table<Device> {
 | 
			
		||||
                        return html`<li>
 | 
			
		||||
                            <a
 | 
			
		||||
                                href="${ifDefined(stage.configureUrl)}${AndNext(
 | 
			
		||||
                                    `${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({
 | 
			
		||||
                                    `${APIConfig.relBase}if/user/#/settings;${JSON.stringify({
 | 
			
		||||
                                        page: "page-mfa",
 | 
			
		||||
                                    })}`,
 | 
			
		||||
                                )}"
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user