Skip to content

web: Clean up usage of server injected values. #14118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion authentik/core/templates/base/header_js.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{% 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>
window.authentik = {
Expand Down
10 changes: 7 additions & 3 deletions authentik/core/views/interface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Interface views"""

from json import dumps
from typing import Any

from django.http import HttpRequest
Expand Down Expand Up @@ -46,14 +45,19 @@
"""Base interface view"""

def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
kwargs["config_json"] = dumps(ConfigView(request=Request(self.request)).get_config().data)
kwargs["brand_json"] = dumps(CurrentBrandSerializer(self.request.brand).data)
"""Add common context data to all interface views"""

kwargs["config_json"] = ConfigView(request=Request(self.request)).get_config().data
kwargs["brand_json"] = CurrentBrandSerializer(self.request.brand).data

Check warning on line 51 in authentik/core/views/interface.py

View check run for this annotation

Codecov / codecov/patch

authentik/core/views/interface.py#L50-L51

Added lines #L50 - L51 were not covered by tests

kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"

kwargs["build"] = get_build_hash()
kwargs["url_kwargs"] = self.kwargs
kwargs["base_url"] = self.request.build_absolute_uri(CONFIG.get("web.path", "/"))
kwargs["base_url_rel"] = CONFIG.get("web.path", "/")

return super().get_context_data(**kwargs)


Expand Down
8 changes: 5 additions & 3 deletions web/src/admin/AdminInterface/AboutModal.ts
Original file line number Diff line number Diff line change
@@ -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 { ServerContext } from "@goauthentik/common/server-context";
import { DefaultBrand } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/EmptyState";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
Expand Down Expand Up @@ -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 (ServerContext.config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
build = msg("Development");
} else if (version.buildHash !== "") {
build = html`<a
Expand All @@ -58,10 +58,12 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
}

renderModal() {
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;

if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
product += ` ${msg("Enterprise")}`;
}

return html`<div
class="pf-c-backdrop"
@click=${(e: PointerEvent) => {
Expand Down
11 changes: 9 additions & 2 deletions web/src/admin/AdminInterface/index.entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
EVENT_NOTIFICATION_DRAWER_TOGGLE,
EVENT_SIDEBAR_TOGGLE,
} from "@goauthentik/common/constants";
import { configureSentry } from "@goauthentik/common/sentry";
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
import { ServerContext } from "@goauthentik/common/server-context";
import { me } from "@goauthentik/common/users";
import { WebsocketClient } from "@goauthentik/common/ws";
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
Expand Down Expand Up @@ -167,15 +168,21 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
}

async firstUpdated(): Promise<void> {
configureSentry(true);
tryInitializeSentry(ServerContext.config);
this.user = await me();

setSentryPII(this.user.user);

const canAccessAdmin =
this.user.user.isSuperuser ||
// TODO: somehow add `access_admin_interface` to the API schema
this.user.user.systemPermissions.includes("access_admin_interface");

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/");
}
}
Expand Down
2 changes: 1 addition & 1 deletion web/src/admin/blueprints/BlueprintForm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import "@goauthentik/components/ak-toggle-group";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
Expand Down
2 changes: 1 addition & 1 deletion web/src/admin/outposts/OutpostDeploymentModal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
import "@goauthentik/elements/buttons/TokenCopyButton";

Expand Down
2 changes: 1 addition & 1 deletion web/src/admin/outposts/OutpostForm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import { groupBy } from "@goauthentik/common/utils";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/forms/FormGroup";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BasePropertyMappingForm } from "@goauthentik/admin/property-mappings/BasePropertyMappingForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { docLink } from "@goauthentik/common/global";
import { docLink } from "@goauthentik/common/server-context";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/forms/FormGroup";
Expand Down
8 changes: 5 additions & 3 deletions web/src/admin/sources/kerberos/KerberosSourceForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ServerContext } from "@goauthentik/common/server-context.js";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-input";
import "@goauthentik/components/ak-textarea-input";
Expand Down Expand Up @@ -60,8 +61,9 @@ export class KerberosSourceForm extends WithCapabilitiesConfig(BaseSourceForm<Ke
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
});
}
const c = await config();
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const { capabilities } = ServerContext.config;

if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const icon = this.getFormFiles()["icon"];
if (icon || this.clearIcon) {
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
Expand Down
8 changes: 5 additions & 3 deletions web/src/admin/sources/oauth/OAuthSourceForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ServerContext } from "@goauthentik/common/server-context.js";
import "@goauthentik/components/ak-radio-input";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
Expand Down Expand Up @@ -85,8 +86,9 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
oAuthSourceRequest: data as unknown as OAuthSourceRequest,
});
}
const c = await config();
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const { capabilities } = ServerContext.config;

if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const icon = this.getFormFiles()["icon"];
if (icon || this.clearIcon) {
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
Expand Down
8 changes: 5 additions & 3 deletions web/src/admin/sources/saml/SAMLSourceForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ServerContext } from "@goauthentik/common/server-context.js";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
Expand Down Expand Up @@ -61,8 +62,9 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
sAMLSourceRequest: data,
});
}
const c = await config();
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const { capabilities } = ServerContext.config;

if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
const icon = this.getFormFiles()["icon"];
if (icon || this.clearIcon) {
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
Expand Down
4 changes: 2 additions & 2 deletions web/src/admin/users/UserImpersonateForm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { globalAK } from "@goauthentik/common/global";
import { ServerContext } from "@goauthentik/common/server-context";
import "@goauthentik/components/ak-text-input";
import { Form } from "@goauthentik/elements/forms/Form";

Expand All @@ -21,7 +21,7 @@ export class UserImpersonateForm extends Form<ImpersonationRequest> {
impersonationRequest: data,
})
.then(() => {
window.location.href = globalAK().api.base;
window.location.href = ServerContext.baseURL;
});
}

Expand Down
33 changes: 6 additions & 27 deletions web/src/common/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,14 @@ import {
LoggingMiddleware,
} from "@goauthentik/common/api/middleware";
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { ServerContext } from "@goauthentik/common/server-context";

import { Config, Configuration, CoreApi, CurrentBrand, RootApi } from "@goauthentik/api";
import { Configuration, CurrentBrand } from "@goauthentik/api";

// 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.
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) {
/**
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
Expand Down Expand Up @@ -52,35 +44,22 @@ 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 {
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`,
basePath: `${ServerContext.baseURL}api/v3`,
headers: {
"sentry-trace": getMetaContent("sentry-trace"),
"sentry-trace": ServerContext.sentryTrace,
},
middleware: [
new CSRFMiddleware(),
new EventMiddleware(),
new LoggingMiddleware(globalAK().brand),
new LoggingMiddleware(ServerContext.brand),
],
});

Expand Down
59 changes: 0 additions & 59 deletions web/src/common/global.ts

This file was deleted.

Loading
Loading