Compare commits
53 Commits
server-con
...
docusaurus
| Author | SHA1 | Date | |
|---|---|---|---|
| 19f706e7aa | |||
| bfdb827ff9 | |||
| 488a58e1c5 | |||
| 3f83e69453 | |||
| e92fa5df0b | |||
| f8c22170df | |||
| e3d08a8434 | |||
| 97d3e9afdc | |||
| 1eb08def73 | |||
| 6e3b379e4a | |||
| 264f59775c | |||
| d048f1ecbd | |||
| eb31f31584 | |||
| fe5c842e92 | |||
| b82d3100c9 | |||
| 49bb668036 | |||
| 52c70c7700 | |||
| b99fd36f86 | |||
| 8a5381eca3 | |||
| 2c77830179 | |||
| ffcd7def60 | |||
| ed121bc2a3 | |||
| d5ab9d9167 | |||
| a983321ad6 | |||
| 9c3420ede4 | |||
| 91b40350aa | |||
| 1912991682 | |||
| 71b9117f53 | |||
| b5f947f460 | |||
| 3a2f7e9549 | |||
| 1582ce0920 | |||
| 6d3eea5266 | |||
| e987208bd1 | |||
| 0efab8eef7 | |||
| 9402dac8ae | |||
| f57a290eee | |||
| 5dab0d2b7a | |||
| 2da6036248 | |||
| cdba94cea4 | |||
| c59eca664a | |||
| d5b205f9c0 | |||
| 8ad9ad833e | |||
| 599ce15f68 | |||
| 91310eff52 | |||
| b522d6732a | |||
| 17d96f204e | |||
| 65e4667bc3 | |||
| f67f9e5ed0 | |||
| 62dd6a4393 | |||
| a46eae8276 | |||
| c4acc9fc24 | |||
| e748a03082 | |||
| e473f28e21 |
2
.github/workflows/ci-outpost.yml
vendored
2
.github/workflows/ci-outpost.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
||||
- name: Generate API
|
||||
run: make gen-client-go
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout 5000s --verbose
|
||||
|
||||
@ -85,18 +85,17 @@ FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
|
||||
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
|
||||
ENV GEOIPUPDATE_VERBOSE="1"
|
||||
ENV GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID"
|
||||
ENV GEOIPUPDATE_LICENSE_KEY_FILE="/run/secrets/GEOIPUPDATE_LICENSE_KEY"
|
||||
|
||||
USER root
|
||||
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
||||
--mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
|
||||
mkdir -p /usr/share/GeoIP && \
|
||||
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
||||
/bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
||||
|
||||
# Stage 5: Download uv
|
||||
FROM ghcr.io/astral-sh/uv:0.7.2 AS uv
|
||||
# Stage 6: Base python image
|
||||
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
|
||||
FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base
|
||||
|
||||
ENV VENV_PATH="/ak-root/.venv" \
|
||||
PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \
|
||||
|
||||
@ -54,7 +54,7 @@ def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedCom
|
||||
return component
|
||||
|
||||
|
||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs): # noqa: W0613
|
||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):
|
||||
"""Workaround to set a default response for endpoints.
|
||||
Workaround suggested at
|
||||
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
|
||||
|
||||
@ -164,9 +164,7 @@ class BlueprintEntry:
|
||||
"""Get the blueprint model, with yaml tags resolved if present"""
|
||||
return str(self.tag_resolver(self.model, blueprint))
|
||||
|
||||
def get_permissions(
|
||||
self, blueprint: "Blueprint"
|
||||
) -> Generator[BlueprintEntryPermission, None, None]:
|
||||
def get_permissions(self, blueprint: "Blueprint") -> Generator[BlueprintEntryPermission]:
|
||||
"""Get permissions of this entry, with all yaml tags resolved"""
|
||||
for perm in self.permissions:
|
||||
yield BlueprintEntryPermission(
|
||||
|
||||
@ -1,14 +1,5 @@
|
||||
{% load i18n %}
|
||||
|
||||
{{ 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 }}">
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
|
||||
<script>
|
||||
window.authentik = {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
"""Interface views"""
|
||||
|
||||
from json import dumps
|
||||
from typing import Any
|
||||
|
||||
from django.http import HttpRequest
|
||||
@ -45,19 +46,14 @@ class InterfaceView(TemplateView):
|
||||
"""Base interface view"""
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||
"""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
|
||||
|
||||
kwargs["config_json"] = dumps(ConfigView(request=Request(self.request)).get_config().data)
|
||||
kwargs["brand_json"] = dumps(CurrentBrandSerializer(self.request.brand).data)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ class LogEventSerializer(PassiveSerializer):
|
||||
|
||||
|
||||
@contextmanager
|
||||
def capture_logs(log_default_output=True) -> Generator[list[LogEvent], None, None]:
|
||||
def capture_logs(log_default_output=True) -> Generator[list[LogEvent]]:
|
||||
"""Capture log entries created"""
|
||||
logs = []
|
||||
cap = LogCapture()
|
||||
|
||||
@ -59,7 +59,7 @@ class PropertyMappingManager:
|
||||
request: HttpRequest | None,
|
||||
return_mapping: bool = False,
|
||||
**kwargs,
|
||||
) -> Generator[tuple[dict, PropertyMapping], None]:
|
||||
) -> Generator[tuple[dict, PropertyMapping]]:
|
||||
"""Iterate over all mappings that were pre-compiled and
|
||||
execute all of them with the given context"""
|
||||
if not self.__has_compiled:
|
||||
|
||||
@ -199,7 +199,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
|
||||
chunk_size = len(ops)
|
||||
if len(ops) < 1:
|
||||
return
|
||||
for chunk in batched(ops, chunk_size):
|
||||
for chunk in batched(ops, chunk_size, strict=False):
|
||||
req = PatchRequest(Operations=list(chunk))
|
||||
self._request(
|
||||
"PATCH",
|
||||
|
||||
8
go.mod
8
go.mod
@ -19,7 +19,7 @@ require (
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
||||
github.com/pires/go-proxyproto v0.8.0
|
||||
github.com/pires/go-proxyproto v0.8.1
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/redis/go-redis/v9 v9.8.0
|
||||
github.com/sethvargo/go-envconfig v1.3.0
|
||||
@ -29,8 +29,8 @@ require (
|
||||
github.com/wwt/guac v1.3.2
|
||||
goauthentik.io/api/v3 v3.2025040.1
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.29.0
|
||||
golang.org/x/sync v0.13.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/sync v0.14.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
||||
)
|
||||
@ -75,7 +75,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
20
go.sum
20
go.sum
@ -230,8 +230,8 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0=
|
||||
github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=
|
||||
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -358,16 +358,16 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -376,8 +376,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -412,8 +412,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
||||
Binary file not shown.
BIN
locale/pt/LC_MESSAGES/django.mo
Normal file
BIN
locale/pt/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
3924
locale/pt/LC_MESSAGES/django.po
Normal file
3924
locale/pt/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
4
packages/docusaurus-config/package-lock.json
generated
4
packages/docusaurus-config/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@goauthentik/docusaurus-config",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@goauthentik/docusaurus-config",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"deepmerge-ts": "^7.1.5",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@goauthentik/docusaurus-config",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"description": "authentik's Docusaurus config",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@ -3,7 +3,7 @@ name = "authentik"
|
||||
version = "2025.4.0"
|
||||
description = ""
|
||||
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
|
||||
requires-python = "==3.12.*"
|
||||
requires-python = "==3.13.*"
|
||||
dependencies = [
|
||||
"argon2-cffi",
|
||||
"celery",
|
||||
@ -52,7 +52,7 @@ dependencies = [
|
||||
"pydantic-scim",
|
||||
"pyjwt",
|
||||
"pyrad",
|
||||
"python-kadmin-rs ==0.6.0",
|
||||
"python-kadmin-rs",
|
||||
"pyyaml",
|
||||
"requests-oauthlib",
|
||||
"scim2-filter-parser",
|
||||
@ -70,7 +70,7 @@ dependencies = [
|
||||
"watchdog",
|
||||
"webauthn",
|
||||
"wsproto",
|
||||
"xmlsec <= 1.3.14",
|
||||
"xmlsec",
|
||||
"zxcvbn",
|
||||
]
|
||||
|
||||
@ -101,6 +101,18 @@ dev = [
|
||||
"selenium",
|
||||
]
|
||||
|
||||
[tool.uv]
|
||||
no-binary-package = [
|
||||
# This differs from the no-binary packages in the Dockerfile. This is due to the fact
|
||||
# that these packages are built from source for different reasons than cryptography and kadmin.
|
||||
# These packages are built from source to link against the libxml2 on the system which is
|
||||
# required for functionality and to stay up-to-date on both libraries.
|
||||
# The other packages specified in the dockerfile are compiled from source to link against the
|
||||
# correct FIPS OpenSSL libraries
|
||||
"lxml",
|
||||
"xmlsec",
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch = "authentik-fixes" }
|
||||
opencontainers = { git = "https://github.com/BeryJu/oci-python", rev = "c791b19056769cd67957322806809ab70f5bead8" }
|
||||
@ -143,12 +155,12 @@ ignore-words = ".github/codespell-words.txt"
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
target-version = ['py312']
|
||||
target-version = ['py313']
|
||||
exclude = 'node_modules'
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py312"
|
||||
target-version = "py313"
|
||||
exclude = ["**/migrations/**", "**/node_modules/**"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
services:
|
||||
chrome:
|
||||
image: docker.io/selenium/standalone-chrome:122.0
|
||||
image: docker.io/selenium/standalone-chrome:136.0
|
||||
volumes:
|
||||
- /dev/shm:/dev/shm
|
||||
network_mode: host
|
||||
restart: always
|
||||
mailpit:
|
||||
image: docker.io/axllent/mailpit:v1.6.5
|
||||
image: docker.io/axllent/mailpit:v1.24.2
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
|
||||
9
web/package-lock.json
generated
9
web/package-lock.json
generated
@ -9472,9 +9472,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001667",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz",
|
||||
"integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==",
|
||||
"version": "1.0.30001716",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001716.tgz",
|
||||
"integrity": "sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -9489,7 +9489,8 @@
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/ccount": {
|
||||
"version": "2.0.1",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
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 "@goauthentik/elements/EmptyState";
|
||||
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 version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
||||
let build: string | TemplateResult = msg("Release");
|
||||
if (ServerContext.config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||
if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||
build = msg("Development");
|
||||
} else if (version.buildHash !== "") {
|
||||
build = html`<a
|
||||
@ -58,12 +58,10 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||
|
||||
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||
product += ` ${msg("Enterprise")}`;
|
||||
}
|
||||
|
||||
return html`<div
|
||||
class="pf-c-backdrop"
|
||||
@click=${(e: PointerEvent) => {
|
||||
|
||||
@ -6,8 +6,7 @@ import {
|
||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||
EVENT_SIDEBAR_TOGGLE,
|
||||
} from "@goauthentik/common/constants";
|
||||
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { configureSentry } from "@goauthentik/common/sentry";
|
||||
import { me } from "@goauthentik/common/users";
|
||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
||||
@ -168,21 +167,15 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
|
||||
}
|
||||
|
||||
async firstUpdated(): Promise<void> {
|
||||
tryInitializeSentry(ServerContext.config);
|
||||
configureSentry(true);
|
||||
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/");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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/elements/CodeMirror";
|
||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { docLink } from "@goauthentik/common/server-context";
|
||||
import { docLink } from "@goauthentik/common/global";
|
||||
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
||||
import "@goauthentik/elements/buttons/TokenCopyButton";
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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 "@goauthentik/elements/CodeMirror";
|
||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
|
||||
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 { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { docLink } from "@goauthentik/common/server-context";
|
||||
import { docLink } from "@goauthentik/common/global";
|
||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||
|
||||
|
||||
@ -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/server-context";
|
||||
import { docLink } from "@goauthentik/common/global";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
|
||||
@ -5,8 +5,7 @@ import {
|
||||
GroupMatchingModeToLabel,
|
||||
UserMatchingModeToLabel,
|
||||
} from "@goauthentik/admin/sources/oauth/utils";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/components/ak-switch-input";
|
||||
import "@goauthentik/components/ak-text-input";
|
||||
import "@goauthentik/components/ak-textarea-input";
|
||||
@ -61,9 +60,8 @@ export class KerberosSourceForm extends WithCapabilitiesConfig(BaseSourceForm<Ke
|
||||
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
|
||||
});
|
||||
}
|
||||
const { capabilities } = ServerContext.config;
|
||||
|
||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||
const c = await config();
|
||||
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||
const icon = this.getFormFiles()["icon"];
|
||||
if (icon || this.clearIcon) {
|
||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||
|
||||
@ -5,8 +5,7 @@ import {
|
||||
GroupMatchingModeToLabel,
|
||||
UserMatchingModeToLabel,
|
||||
} from "@goauthentik/admin/sources/oauth/utils";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/components/ak-radio-input";
|
||||
import "@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,
|
||||
});
|
||||
}
|
||||
const { capabilities } = ServerContext.config;
|
||||
|
||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||
const c = await config();
|
||||
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||
const icon = this.getFormFiles()["icon"];
|
||||
if (icon || this.clearIcon) {
|
||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||
|
||||
@ -6,8 +6,7 @@ import {
|
||||
GroupMatchingModeToLabel,
|
||||
UserMatchingModeToLabel,
|
||||
} from "@goauthentik/admin/sources/oauth/utils";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
||||
import {
|
||||
CapabilitiesEnum,
|
||||
WithCapabilitiesConfig,
|
||||
@ -62,9 +61,8 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
|
||||
sAMLSourceRequest: data,
|
||||
});
|
||||
}
|
||||
const { capabilities } = ServerContext.config;
|
||||
|
||||
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||
const c = await config();
|
||||
if (c.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 { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } 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 = ServerContext.baseURL;
|
||||
window.location.href = globalAK().api.base;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -5,14 +5,22 @@ import {
|
||||
LoggingMiddleware,
|
||||
} from "@goauthentik/common/api/middleware";
|
||||
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.
|
||||
// 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">
|
||||
@ -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 {
|
||||
const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
|
||||
if (!metaEl) return "";
|
||||
|
||||
return metaEl.content;
|
||||
}
|
||||
|
||||
export const DEFAULT_CONFIG = new Configuration({
|
||||
basePath: `${ServerContext.baseURL}api/v3`,
|
||||
basePath: `${globalAK().api.base}api/v3`,
|
||||
headers: {
|
||||
"sentry-trace": ServerContext.sentryTrace,
|
||||
"sentry-trace": getMetaContent("sentry-trace"),
|
||||
},
|
||||
middleware: [
|
||||
new CSRFMiddleware(),
|
||||
new EventMiddleware(),
|
||||
new LoggingMiddleware(ServerContext.brand),
|
||||
new LoggingMiddleware(globalAK().brand),
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
59
web/src/common/global.ts
Normal file
59
web/src/common/global.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
|
||||
|
||||
export interface GlobalAuthentik {
|
||||
_converted?: boolean;
|
||||
locale?: string;
|
||||
flow?: {
|
||||
layout: string;
|
||||
};
|
||||
config: Config;
|
||||
brand: CurrentBrand;
|
||||
versionFamily: string;
|
||||
versionSubdomain: string;
|
||||
build: string;
|
||||
api: {
|
||||
base: string;
|
||||
relBase: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AuthentikWindow {
|
||||
authentik: GlobalAuthentik;
|
||||
}
|
||||
|
||||
export function globalAK(): GlobalAuthentik {
|
||||
const ak = (window as unknown as AuthentikWindow).authentik;
|
||||
if (ak && !ak._converted) {
|
||||
ak._converted = true;
|
||||
ak.brand = CurrentBrandFromJSON(ak.brand);
|
||||
ak.config = ConfigFromJSON(ak.config);
|
||||
}
|
||||
const apiBase = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||
if (!ak) {
|
||||
return {
|
||||
config: ConfigFromJSON({
|
||||
capabilities: [],
|
||||
}),
|
||||
brand: CurrentBrandFromJSON({
|
||||
ui_footer_links: [],
|
||||
}),
|
||||
versionFamily: "",
|
||||
versionSubdomain: "",
|
||||
build: "",
|
||||
api: {
|
||||
base: apiBase.toString(),
|
||||
relBase: apiBase.pathname,
|
||||
},
|
||||
};
|
||||
}
|
||||
return ak;
|
||||
}
|
||||
|
||||
export function docLink(path: string): string {
|
||||
const ak = globalAK();
|
||||
// Default case or beta build which should always point to latest
|
||||
if (!ak || ak.build !== "") {
|
||||
return `https://goauthentik.io${path}`;
|
||||
}
|
||||
return `https://${ak.versionSubdomain}.goauthentik.io${path}`;
|
||||
}
|
||||
@ -1,131 +1,89 @@
|
||||
import { config } from "@goauthentik/common/api/config";
|
||||
import { VERSION } from "@goauthentik/common/constants";
|
||||
import { RouteInterfaceName, readInterfaceRouteParam } from "@goauthentik/elements/router/utils";
|
||||
import { BrowserOptions, browserTracingIntegration, init, setTag, setUser } from "@sentry/browser";
|
||||
import { me } from "@goauthentik/common/users";
|
||||
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.
|
||||
*
|
||||
* @category Sentry
|
||||
*/
|
||||
export class SentryIgnoredError extends Error {}
|
||||
|
||||
/**
|
||||
* Attempt initializing Spotlight.
|
||||
*
|
||||
* @see {@link https://spotlightjs.com/ Spotlight}
|
||||
* @category Sentry
|
||||
*/
|
||||
export async function tryInitializingSpotlight() {
|
||||
return import("@spotlightjs/spotlight").then((Spotlight) =>
|
||||
Spotlight.init({ injectImmediately: true }),
|
||||
);
|
||||
}
|
||||
export const TAG_SENTRY_COMPONENT = "authentik.component";
|
||||
export const TAG_SENTRY_CAPABILITIES = "authentik.capabilities";
|
||||
|
||||
/**
|
||||
* Default Sentry options for the browser.
|
||||
*
|
||||
* @category Sentry
|
||||
*/
|
||||
const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
||||
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);
|
||||
export async function configureSentry(canDoPpi = false): Promise<Config> {
|
||||
const cfg = await config();
|
||||
|
||||
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;
|
||||
},
|
||||
}),
|
||||
],
|
||||
beforeSend: (event, hint) => {
|
||||
if (!hint) {
|
||||
return event;
|
||||
});
|
||||
setTag(TAG_SENTRY_CAPABILITIES, cfg.capabilities.join(","));
|
||||
if (window.location.pathname.includes("if/")) {
|
||||
setTag(TAG_SENTRY_COMPONENT, `web/${readInterfaceRouteParam()}`);
|
||||
}
|
||||
if (hint.originalException instanceof SentryIgnoredError) {
|
||||
return null;
|
||||
if (cfg.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||
const Spotlight = await import("@spotlightjs/spotlight");
|
||||
|
||||
Spotlight.init({ injectImmediately: true });
|
||||
}
|
||||
if (
|
||||
hint.originalException instanceof ResponseError ||
|
||||
hint.originalException instanceof DOMException
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
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);
|
||||
if (cfg.errorReporting.sendPii && canDoPpi) {
|
||||
me().then((user) => {
|
||||
setUser({ email: user.user.email });
|
||||
console.debug("authentik/config: Sentry with PII enabled.");
|
||||
});
|
||||
} else {
|
||||
console.debug("authentik/config: Sentry enabled.");
|
||||
}
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
|
||||
@ -1,116 +0,0 @@
|
||||
/**
|
||||
* @file Server context singleton.
|
||||
*/
|
||||
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
|
||||
|
||||
function readMetaElement(key: string, fallback: string = ""): string {
|
||||
const metaElement = document.querySelector<HTMLMetaElement>(`meta[name="${key}"]`);
|
||||
const value = metaElement?.getAttribute("content") || fallback;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
interface ServerContextValue {
|
||||
/**
|
||||
* Server-injected authentik configuration.
|
||||
*/
|
||||
config: Readonly<Config>;
|
||||
|
||||
/**
|
||||
* Brand information used to customize the UI.
|
||||
*/
|
||||
brand: Readonly<CurrentBrand>;
|
||||
|
||||
/**
|
||||
* A semantic versioning string representing the current version of authentik.
|
||||
*/
|
||||
versionFamily: string;
|
||||
|
||||
/**
|
||||
* A subdomain-compatible version string representing the current version of authentik.
|
||||
*/
|
||||
versionSubdomain: string;
|
||||
|
||||
/**
|
||||
* A build hash string representing the current build of authentik.
|
||||
*/
|
||||
build: string;
|
||||
|
||||
/**
|
||||
* The base URL of the authentik instance.
|
||||
*/
|
||||
baseURL: string;
|
||||
|
||||
/**
|
||||
* The relative base URL of the authentik instance.
|
||||
*/
|
||||
baseURLRelative: string;
|
||||
|
||||
/**
|
||||
* The layout of the flow, if any.
|
||||
*/
|
||||
flowLayout: string;
|
||||
|
||||
/**
|
||||
* The Sentry trace ID for the current request.
|
||||
*/
|
||||
sentryTrace: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the server context from the DOM.
|
||||
*/
|
||||
export function refreshServerContext(): Readonly<ServerContextValue> {
|
||||
const configElement = document.getElementById(":ak-config:");
|
||||
|
||||
const config = configElement?.textContent
|
||||
? ConfigFromJSON(JSON.parse(configElement.textContent))
|
||||
: ConfigFromJSON({
|
||||
capabilities: [],
|
||||
});
|
||||
|
||||
const brandElement = document.getElementById(":ak-brand:");
|
||||
|
||||
const brand = brandElement?.textContent
|
||||
? CurrentBrandFromJSON(JSON.parse(brandElement.textContent))
|
||||
: CurrentBrandFromJSON({
|
||||
ui_footer_links: [],
|
||||
});
|
||||
|
||||
const apiBaseURL = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||
|
||||
const value: ServerContextValue = {
|
||||
sentryTrace: readMetaElement("sentry-trace"),
|
||||
baseURL: readMetaElement("ak-base-url") || apiBaseURL.toString(),
|
||||
baseURLRelative: readMetaElement("ak-base-url-rel"),
|
||||
|
||||
versionFamily: readMetaElement("ak-version-family"),
|
||||
versionSubdomain: readMetaElement("ak-version-subdomain"),
|
||||
|
||||
build: readMetaElement("ak-build"),
|
||||
|
||||
flowLayout: readMetaElement("ak-flow-layout"),
|
||||
config,
|
||||
brand,
|
||||
};
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Server injected values used to configure application.
|
||||
*
|
||||
* @singleton
|
||||
*/
|
||||
export const ServerContext = refreshServerContext();
|
||||
|
||||
export function docLink(path: string): string {
|
||||
const { build, versionSubdomain } = ServerContext;
|
||||
|
||||
// Default case or beta build which should always point to latest
|
||||
if (build) {
|
||||
return new URL(path, "https://goauthentik.io").toString();
|
||||
}
|
||||
|
||||
return new URL(path, `https://${versionSubdomain}.goauthentik.io`).toString();
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { MessageLevel } from "@goauthentik/common/messages";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
|
||||
@ -22,14 +22,11 @@ export class WebsocketClient {
|
||||
|
||||
connect(): void {
|
||||
if (navigator.webdriver) return;
|
||||
|
||||
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 apiURL = new URL(globalAK().api.base);
|
||||
const wsUrl = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
|
||||
this.messageSocket = new WebSocket(wsUrl);
|
||||
this.messageSocket.addEventListener("open", () => {
|
||||
console.debug(`authentik/ws: connected to ${wsURL}`);
|
||||
console.debug(`authentik/ws: connected to ${wsUrl}`);
|
||||
this.retryDelay = 200;
|
||||
});
|
||||
this.messageSocket.addEventListener("close", (e) => {
|
||||
|
||||
@ -3,7 +3,7 @@ import {
|
||||
EVENT_API_DRAWER_TOGGLE,
|
||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||
} 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 { 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="${ServerContext.baseURL}if/user/#/settings"
|
||||
href="${globalAK().api.base}if/user/#/settings"
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Settings")}>
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
@ -200,7 +200,7 @@ export class NavigationButtons extends AKElement {
|
||||
${this.renderSettings()}
|
||||
<div class="pf-c-page__header-tools-item">
|
||||
<a
|
||||
href="${ServerContext.baseURL}flows/-/default/invalidation/"
|
||||
href="${globalAK().api.base}flows/-/default/invalidation/"
|
||||
class="pf-c-button pf-m-plain"
|
||||
>
|
||||
<pf-tooltip position="top" content=${msg("Sign out")}>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import {
|
||||
StyleSheetInit,
|
||||
StyleSheetParent,
|
||||
@ -82,7 +82,7 @@ export class AKElement extends LitElement implements ThemedElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const { brand } = ServerContext;
|
||||
const { brand } = globalAK();
|
||||
|
||||
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
|
||||
this.activeTheme = resolveUITheme(brand?.uiTheme);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
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 { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
|
||||
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
|
||||
@ -23,8 +23,8 @@ export class ConfigContextController implements ReactiveController {
|
||||
initialValue: undefined,
|
||||
});
|
||||
// Pre-hydrate from template-embedded config
|
||||
this.context.setValue(ServerContext.config);
|
||||
this.host.config = ServerContext.config;
|
||||
this.context.setValue(globalAK().config);
|
||||
this.host.config = globalAK().config;
|
||||
this.fetch = this.fetch.bind(this);
|
||||
this.fetch();
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@ import {
|
||||
EVENT_WS_MESSAGE,
|
||||
TITLE_DEFAULT,
|
||||
} from "@goauthentik/common/constants";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { getConfigForUser } from "@goauthentik/common/ui/config";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { UIConfig, UserDisplay, getConfigForUser } 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 "@goauthentik/components/ak-nav-buttons";
|
||||
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}>
|
||||
<a
|
||||
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"
|
||||
>
|
||||
${msg("User interface")}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
|
||||
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
|
||||
import { AkLocale } from "./types";
|
||||
|
||||
@ -49,7 +51,7 @@ export function autoDetectLanguage(userReq = TOMBSTONE, brandReq = TOMBSTONE): s
|
||||
userReq,
|
||||
window.navigator?.language ?? TOMBSTONE,
|
||||
brandReq,
|
||||
document.documentElement.getAttribute("lang") ?? TOMBSTONE,
|
||||
globalAK()?.locale ?? TOMBSTONE,
|
||||
DEFAULT_LOCALE,
|
||||
].filter(isLocaleCandidate);
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||
|
||||
@ -76,7 +76,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
|
||||
: "pf-m-gold"}"
|
||||
>
|
||||
${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
|
||||
>
|
||||
</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 { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } 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="${ServerContext.baseURL}api/v3/" target="_blank"
|
||||
<a href="${globalAK().api.base}api/v3/" target="_blank"
|
||||
>${msg("Open API Browser")}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
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 { actionToLabel } from "@goauthentik/common/labels";
|
||||
import { MessageLevel } from "@goauthentik/common/messages";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||
import { me } from "@goauthentik/common/users";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
@ -99,7 +99,7 @@ export class NotificationDrawer extends AKElement {
|
||||
html`
|
||||
<a
|
||||
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")}>
|
||||
<i class="fas fa-share-square"></i>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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 { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||
@ -45,7 +45,7 @@ export class SidebarVersion extends WithLicenseSummary(WithVersion(AKElement)) {
|
||||
if (!this.version || !this.licenseSummary) {
|
||||
return nothing;
|
||||
}
|
||||
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||
product += ` ${msg("Enterprise")}`;
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import {
|
||||
EVENT_FLOW_INSPECTOR_TOGGLE,
|
||||
TITLE_DEFAULT,
|
||||
} from "@goauthentik/common/constants";
|
||||
import { tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { configureSentry } from "@goauthentik/common/sentry";
|
||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||
import { Interface } from "@goauthentik/elements/Interface";
|
||||
@ -237,12 +237,10 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
}
|
||||
|
||||
async firstUpdated(): Promise<void> {
|
||||
tryInitializeSentry(ServerContext.config);
|
||||
|
||||
configureSentry();
|
||||
if (this.config?.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||
this.inspectorAvailable = true;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
try {
|
||||
const challenge = await new FlowsApi(DEFAULT_CONFIG).flowsExecutorGet({
|
||||
@ -483,8 +481,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
}
|
||||
|
||||
getLayout(): string {
|
||||
const prefilledFlow = ServerContext.flowLayout || FlowLayoutEnum.Stacked;
|
||||
|
||||
const prefilledFlow = globalAK()?.flow?.layout || FlowLayoutEnum.Stacked;
|
||||
if (this.challenge) {
|
||||
return this.challenge?.flowInfo?.layout || prefilledFlow;
|
||||
}
|
||||
@ -524,7 +521,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
<img
|
||||
src="${themeImage(
|
||||
this.brand?.brandingLogo ??
|
||||
ServerContext.brand.brandingLogo ??
|
||||
globalAK()?.brand.brandingLogo ??
|
||||
DefaultBrand.brandingLogo,
|
||||
)}"
|
||||
alt="${msg("authentik Logo")}"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import { 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="${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")}
|
||||
</a>
|
||||
${this.challenge.invalidationFlowUrl
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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 "@goauthentik/elements/AppIcon";
|
||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||
@ -82,7 +82,8 @@ export class LibraryApplication extends AKElement {
|
||||
? html`
|
||||
<a
|
||||
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
||||
href="${ServerContext.baseURL}if/admin/#/core/applications/${application?.slug}"
|
||||
href="${globalAK().api
|
||||
.base}if/admin/#/core/applications/${application?.slug}"
|
||||
>
|
||||
<i class="fas fa-edit"></i> ${msg("Edit")}
|
||||
</a>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServerContext, docLink } from "@goauthentik/common/server-context";
|
||||
import { docLink, globalAK } from "@goauthentik/common/global";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { 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="${ServerContext.baseURL}if/admin/${href}"
|
||||
href="${globalAK().api.base}if/admin/${href}"
|
||||
>${msg("Create a new application")}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
@ -4,8 +4,8 @@ import {
|
||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||
EVENT_WS_MESSAGE,
|
||||
} from "@goauthentik/common/constants";
|
||||
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { configureSentry } from "@goauthentik/common/sentry";
|
||||
import { UIConfig, getConfigForUser } from "@goauthentik/common/ui/config";
|
||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||
import { me } from "@goauthentik/common/users";
|
||||
@ -170,14 +170,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="${ServerContext.baseURL}if/admin/"
|
||||
href="${globalAK().api.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="${ServerContext.baseURL}if/admin/"
|
||||
href="${globalAK().api.base}if/admin/"
|
||||
slot="extra"
|
||||
>
|
||||
${msg("Admin")}
|
||||
@ -284,9 +284,7 @@ export class UserInterface extends AuthenticatedInterface {
|
||||
super();
|
||||
this.ws = new WebsocketClient();
|
||||
this.fetchConfigurationDetails();
|
||||
|
||||
tryInitializeSentry(ServerContext.config);
|
||||
|
||||
configureSentry(true);
|
||||
this.toggleNotificationDrawer = this.toggleNotificationDrawer.bind(this);
|
||||
this.toggleApiDrawer = this.toggleApiDrawer.bind(this);
|
||||
this.fetchConfigurationDetails = this.fetchConfigurationDetails.bind(this);
|
||||
@ -327,8 +325,6 @@ export class UserInterface extends AuthenticatedInterface {
|
||||
this.me = session;
|
||||
this.uiConfig = getConfigForUser(session.user);
|
||||
|
||||
setSentryPII(session.user);
|
||||
|
||||
new EventsApi(DEFAULT_CONFIG)
|
||||
.eventsNotificationsList({
|
||||
seen: false,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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 { 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(
|
||||
`${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"
|
||||
>
|
||||
|
||||
@ -5,8 +5,8 @@ import {
|
||||
parseAPIResponseError,
|
||||
pluckErrorDetail,
|
||||
} from "@goauthentik/common/errors/network";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { MessageLevel } from "@goauthentik/common/messages";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { refreshMe } from "@goauthentik/common/users";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||
@ -181,7 +181,7 @@ export class UserSettingsFlowExecutor
|
||||
);
|
||||
return html`
|
||||
<a
|
||||
href="${ServerContext.baseURL}if/flow/${this.flowSlug}/"
|
||||
href="${globalAK().api.base}if/flow/${this.flowSlug}/"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>
|
||||
${msg("Open settings")}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
||||
|
||||
@ -51,7 +51,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
||||
${this.host.brand?.flowUnenrollment
|
||||
? html` <a
|
||||
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}/"
|
||||
>
|
||||
${msg("Delete account")}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { deviceTypeName } from "@goauthentik/common/labels";
|
||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
||||
import { ServerContext } from "@goauthentik/common/server-context";
|
||||
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(
|
||||
`${ServerContext.baseURL}if/user/#/settings;${JSON.stringify({
|
||||
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({
|
||||
page: "page-mfa",
|
||||
})}`,
|
||||
)}"
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Willkommen,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9171,6 +9171,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -493,7 +493,7 @@
|
||||
<target>General system status</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Welcome,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
</trans-unit>
|
||||
@ -7694,6 +7694,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Bienvenido,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9253,6 +9253,9 @@ Las vinculaciones a grupos o usuarios se comparan con el usuario del evento.</ta
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Bienvenue,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9805,6 +9805,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
<target>Nombre d'anciens mots de passe à vérifier</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Benvenuto,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9779,6 +9779,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -597,7 +597,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sc381422c585b867f">
|
||||
@ -9161,6 +9161,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -605,7 +605,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Welkom,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9063,6 +9063,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Witaj,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9488,6 +9488,9 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -603,7 +603,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Ŵēĺćōḿē, <x id="0" equiv-text="${name || ""}"/>.</target>
|
||||
|
||||
</trans-unit>
|
||||
@ -9496,4 +9496,7 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body></file></xliff>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Добро пожаловать,
|
||||
<x id="0" equiv-text="${name}"/>.</target>
|
||||
|
||||
@ -9581,6 +9581,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -602,7 +602,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>Hoş geldiniz, <x id="0" equiv-text="${name || ""}"/>.</target>
|
||||
|
||||
</trans-unit>
|
||||
@ -9551,6 +9551,9 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -399,7 +399,7 @@
|
||||
<source>General system status</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc381422c585b867f">
|
||||
<source>Quick actions</source>
|
||||
@ -6302,6 +6302,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>欢迎,
|
||||
<x id="0" equiv-text="${name}"/>。</target>
|
||||
|
||||
@ -9806,6 +9806,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
<target>检查历史密码数量</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
<target>切换侧边栏</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -485,7 +485,7 @@
|
||||
<target>常规系统状态</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>欢迎,
|
||||
<x id="0" equiv-text="${name}"/>。</target>
|
||||
</trans-unit>
|
||||
@ -7394,6 +7394,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -612,7 +612,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
<target>欢迎,
|
||||
<x id="0" equiv-text="${name}"/>。</target>
|
||||
|
||||
@ -9806,6 +9806,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
<target>检查历史密码数量</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
<target>切换侧边栏</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -596,7 +596,7 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s6dfd15978586d05f">
|
||||
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sc381422c585b867f">
|
||||
@ -9138,6 +9138,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s79b3fcd40dd63921">
|
||||
<source>Number of previous passwords to check</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sdd66c5a2e706fb81">
|
||||
<source>Toggle sidebar</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
2
website/.gitignore
vendored
2
website/.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
|
||||
# Production
|
||||
/build
|
||||
/out
|
||||
/help
|
||||
|
||||
# Generated files
|
||||
@ -25,4 +26,5 @@ yarn-error.log*
|
||||
|
||||
static/docker-compose.yml
|
||||
static/schema.yml
|
||||
static/releases.gen.json
|
||||
docs/developer-docs/api/reference/**
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# Ignore artifacts:
|
||||
build
|
||||
out
|
||||
coverage
|
||||
.docusaurus
|
||||
node_modules
|
||||
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -1,9 +1,8 @@
|
||||
---
|
||||
title: Email Authenticator Setup stage
|
||||
authentik_version: "2025.2"
|
||||
---
|
||||
|
||||
<span class="badge badge--version">authentik 2025.2+</span>
|
||||
|
||||
This stage configures an email-based authenticator that sends a one-time code to a user's email address for authentication.
|
||||
|
||||
When a user goes through a flow that includes this stage, they are prompted for their email address (if not already set). The user then receives an email with a one-time code, which they enter into the authentik Login panel.
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
title: WebAuthn / Passkeys Authenticator setup stage
|
||||
---
|
||||
|
||||
<span class="badge badge--version">authentik 2021.3.1+</span>
|
||||
|
||||
This stage configures a WebAuthn-based Authenticator. This can either be a browser, biometrics or a Security stick like a YubiKey.
|
||||
|
||||
### Options
|
||||
|
||||
@ -29,8 +29,8 @@ You can also use custom email templates, to use your own design or layout.
|
||||
Starting with authentik 2024.2, it is possible to create `.txt` files with the same name as the `.html` template. If a matching `.txt` file exists, the email sent will be a multipart email with both the text and HTML template.
|
||||
:::
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs
|
||||
defaultValue="docker-compose"
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
title: Caddy
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
import Placeholders from "./__placeholders.md";
|
||||
import CaddyStandalone from "./_caddy_standalone.md";
|
||||
|
||||
|
||||
@ -2,13 +2,12 @@
|
||||
title: Envoy
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
import Placeholders from "./__placeholders.md";
|
||||
import EnvoyIstio from "./_envoy_istio.md";
|
||||
|
||||
# Envoy
|
||||
|
||||
The configuration template shown below apply to both single-application and domain-level forward auth.
|
||||
|
||||
:::info
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
# nginx
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
# Traefik
|
||||
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
const RADIUSProtocols = [
|
||||
"PAP",
|
||||
"CHAP",
|
||||
"Digest",
|
||||
"MS-CHAP",
|
||||
"PEAP",
|
||||
"MS-CHAPv2",
|
||||
"Cisco LEAP",
|
||||
"EAP-GTC",
|
||||
"EAP-MD5",
|
||||
"EAP-PWD",
|
||||
] as const satisfies string[];
|
||||
|
||||
type RADIUSProtocol = (typeof RADIUSProtocols)[number];
|
||||
|
||||
const HashKinds = [
|
||||
"Cleartext",
|
||||
"NT",
|
||||
"MD5",
|
||||
"Salted MD5",
|
||||
"SHA1",
|
||||
"Salted SHA1",
|
||||
"Unix Crypt",
|
||||
] as const satisfies string[];
|
||||
|
||||
type HashKind = (typeof HashKinds)[number];
|
||||
|
||||
const supportMatrix: Record<HashKind, RADIUSProtocol[]> = {
|
||||
"Cleartext": [
|
||||
"PAP",
|
||||
"CHAP",
|
||||
"Digest",
|
||||
"MS-CHAP",
|
||||
"PEAP",
|
||||
"MS-CHAPv2",
|
||||
"Cisco LEAP",
|
||||
"EAP-GTC",
|
||||
"EAP-MD5",
|
||||
"EAP-PWD",
|
||||
],
|
||||
"NT": ["PAP", "MS-CHAP", "PEAP", "MS-CHAPv2", "Cisco LEAP", "EAP-GTC"],
|
||||
"MD5": ["PAP", "EAP-GTC"],
|
||||
"Salted MD5": ["PAP", "EAP-GTC"],
|
||||
"SHA1": ["PAP", "EAP-GTC"],
|
||||
"Salted SHA1": ["PAP", "EAP-GTC", "EAP-PWD"],
|
||||
"Unix Crypt": ["PAP", "EAP-GTC", "EAP-PWD"],
|
||||
};
|
||||
|
||||
export const HashSupport: React.FC = () => {
|
||||
return (
|
||||
<table className={styles.table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{HashKinds.map((hashKind, i) => (
|
||||
<th key={i}>{hashKind}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{RADIUSProtocols.map((radiusProtocol, i) => (
|
||||
<tr key={i}>
|
||||
<td>{radiusProtocol}</td>
|
||||
{HashKinds.map((hashKind) => {
|
||||
const protocols = supportMatrix[hashKind];
|
||||
const supported = protocols.includes(radiusProtocol);
|
||||
|
||||
return (
|
||||
<td data-supported={supported} key={hashKind}>
|
||||
{supported ? "✓" : "✗"}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
@ -2,7 +2,7 @@
|
||||
title: RADIUS Provider
|
||||
---
|
||||
|
||||
import { Check, X, AlertTriangle } from "react-feather";
|
||||
import { HashSupport } from "./HashSupport";
|
||||
|
||||
You can configure a Radius provider for applications that don't support any other protocols or that require Radius.
|
||||
|
||||
@ -56,15 +56,4 @@ After creation, make sure to select the RADIUS property mapping in the RADIUS pr
|
||||
|
||||
The RADIUS provider only supports the [PAP](https://en.wikipedia.org/wiki/Password_Authentication_Protocol) (Password Authentication Protocol) protocol:
|
||||
|
||||
| | Clear-text | NT hash | MD5 hash | Salted MD5 hash | SHA1 hash | Salted SHA1 hash | Unix Crypt |
|
||||
| ------------ | --------------- | --------------- | --------------- | --------------- | --------------- | ---------------- | --------------- |
|
||||
| PAP | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> |
|
||||
| CHAP | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| Digest | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| MS-CHAP | <Check></Check> | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| PEAP | <Check></Check> | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| EAP-MSCHAPv2 | <Check></Check> | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| Cisco LEAP | <Check></Check> | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| EAP-GTC | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> | <Check></Check> |
|
||||
| EAP-MD5 | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> | <X></X> |
|
||||
| EAP-PWD | <Check></Check> | <X></X> | <X></X> | <X></X> | <X></X> | <Check></Check> | <Check></Check> |
|
||||
<HashSupport />
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
.table td {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
||||
&:first-child {
|
||||
text-align: right;
|
||||
width: 13ch;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
width: 10ch;
|
||||
}
|
||||
|
||||
&[data-supported="true"] {
|
||||
color: var(--ifm-color-success-dark);
|
||||
}
|
||||
&[data-supported="false"] {
|
||||
color: var(--ifm-color-danger-dark);
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ title: Example
|
||||
|
||||
This is one of the default packaged blueprints to create the default authentication flow.
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
```yaml
|
||||
version: 1
|
||||
metadata:
|
||||
@ -64,3 +65,4 @@ entries:
|
||||
target: !KeyOf flow
|
||||
model: authentik_flows.flowstagebinding
|
||||
```
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -48,6 +48,8 @@ Returns the value of the given environment variable. Can be used as a scalar wit
|
||||
|
||||
Examples:
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
|
||||
```yaml
|
||||
configure_flow: !Find [authentik_flows.flow, [slug, default-password-change]]
|
||||
```
|
||||
@ -60,6 +62,8 @@ configure_flow:
|
||||
]
|
||||
```
|
||||
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
Looks up any model and resolves to the the matches' primary key.
|
||||
First argument is the model to be queried, remaining arguments are expected to be pairs of key=value pairs to query for.
|
||||
|
||||
@ -67,10 +71,15 @@ First argument is the model to be queried, remaining arguments are expected to b
|
||||
|
||||
Example:
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
|
||||
|
||||
```yaml
|
||||
configure_flow: !Context foo
|
||||
```
|
||||
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
Find values from the context. Can optionally be called with a default like `!Context [foo, default-value]`.
|
||||
|
||||
#### `!Format`
|
||||
@ -209,6 +218,8 @@ For example, given a sequence like this - `["a", "b", "c"]`, this tag will resol
|
||||
|
||||
Minimal examples:
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
|
||||
```yaml
|
||||
configuration_stages: !Enumerate [
|
||||
!Context map_of_totp_stage_names_and_types,
|
||||
@ -224,6 +235,8 @@ configuration_stages: !Enumerate [
|
||||
]
|
||||
```
|
||||
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
The above example will resolve to something like this:
|
||||
|
||||
```yaml
|
||||
@ -265,6 +278,8 @@ Full example:
|
||||
Note that an `!Enumeration` tag's iterable can never be an `!Item` or `!Value` tag with a depth of `0`. Minimum depth allowed is `1`. This is because a depth of `0` refers to the `!Enumeration` tag the `!Item` or `!Value` tag is in, and an `!Enumeration` tag cannot iterate over itself.
|
||||
:::
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
|
||||
```yaml
|
||||
example: !Enumerate [
|
||||
!Context sequence, # ["foo", "bar"]
|
||||
@ -288,6 +303,8 @@ example: !Enumerate [
|
||||
]
|
||||
```
|
||||
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
The above example will resolve to something like this:
|
||||
|
||||
```yaml
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
To further modify the look of authentik, a custom CSS file can be created. Creating such a file is outside the scope of this document.
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs
|
||||
defaultValue="docker-compose"
|
||||
|
||||
@ -255,8 +255,8 @@ This section covers the usage of React components within our documentation. File
|
||||
Use **Tabs** to display different configurations (e.g., setting up authentication with OIDC vs. SAML) to help users navigate between options. Default to the easier or more common option. Insert the following lines wherever you want the code block to appear:
|
||||
|
||||
```jsx
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs
|
||||
defaultValue="oidc"
|
||||
|
||||
@ -163,7 +163,7 @@ While the prerequisites above must be satisfied prior to having your pull reques
|
||||
|
||||
All Python code is linted with [black](https://black.readthedocs.io/en/stable/) and [Ruff](https://docs.astral.sh/ruff).
|
||||
|
||||
authentik runs on Python 3.12 at the time of writing this.
|
||||
authentik runs on Python 3.13 at the time of writing this.
|
||||
|
||||
- Use native type-annotations wherever possible.
|
||||
- Add meaningful docstrings when possible.
|
||||
|
||||
@ -148,7 +148,6 @@ We'll be publishing a security Issue (CVE-2022-xxxxx) and accompanying fix on _d
|
||||
|
||||
<details>
|
||||
<summary>Mailing list template</summary>
|
||||
<p>
|
||||
|
||||
Subject: `Release of authentik Security releases 2022.10.3 and 2022.11.3`
|
||||
|
||||
@ -158,12 +157,10 @@ The security advisory for CVE-2022-xxxxx has been published: https://github.com/
|
||||
Releases 2022.10.3 and 2022.11.3 with fixes included are available here: https://github.com/goauthentik/authentik/releases
|
||||
```
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Discord template</summary>
|
||||
<p>
|
||||
|
||||
```markdown
|
||||
[...existing announcement...]
|
||||
@ -175,5 +172,4 @@ Advisory for for CVE-2022-xxxxx has been published here https://github.com/goaut
|
||||
The fixed versions 2022.10.3 and 2022.11.3 are available here: https://github.com/goauthentik/authentik/releases
|
||||
```
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
@ -9,15 +9,15 @@ tags:
|
||||
- docker
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Python](https://www.python.org/) (3.12 or later)
|
||||
- [Python](https://www.python.org/) (3.13 or later)
|
||||
- [uv](https://docs.astral.sh/uv/getting-started/installation/), (Latest stable release)
|
||||
- [Go](https://go.dev/) (1.23 or later)
|
||||
- [Go](https://go.dev/) (1.24 or later)
|
||||
- [Node.js](https://nodejs.org/en) (22 or later)
|
||||
- [PostgreSQL](https://www.postgresql.org/) (16 or later)
|
||||
- [Redis](https://redis.io/) (7 or later)
|
||||
@ -54,9 +54,8 @@ values={[
|
||||
To install the native dependencies on macOS, run:
|
||||
|
||||
```sh
|
||||
$ pip install uv
|
||||
$ brew install libxmlsec1 libpq krb5 # Required development libraries,
|
||||
$ brew install postgresql redis node@22 golangci-lint # Required CLI tools
|
||||
$ brew install libxmlsec1 libpq krb5 pkg-config # Required development libraries,
|
||||
$ brew install uv postgresql redis node@22 golangci-lint # Required CLI tools
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -66,14 +65,13 @@ To install native dependencies on Debian or Ubuntu, run:
|
||||
|
||||
```sh
|
||||
$ pip install uv
|
||||
$ sudo apt-get install libgss-dev krb5-config libkrb5-dev postgresql-server-dev-all
|
||||
$ sudo apt-get install libgss-dev krb5-config libkrb5-dev postgresql-server-dev-all
|
||||
$ sudo apt-get install postresql redis
|
||||
```
|
||||
|
||||
Adjust your needs as required for other distributions such as Red Hat, SUSE, or Arch.
|
||||
|
||||
Install golangci-lint locally [from the site
|
||||
instructions](https://golangci-lint.run/welcome/install/#other-ci).
|
||||
Install golangci-lint locally [from the site instructions](https://golangci-lint.run/welcome/install/#other-ci).
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
||||
@ -24,39 +24,34 @@ The authentik product provides the following consoles:
|
||||
|
||||
In authentik, you can use Light or Dark mode for the Admin interface, User interface, and the Flow interface.
|
||||
|
||||
import "react-before-after-slider-component/dist/build.css";
|
||||
import ReactBeforeSliderComponent from "react-before-after-slider-component";
|
||||
import useBaseUrl from "@docusaurus/useBaseUrl";
|
||||
import ReactBeforeSliderComponent from "react-before-after-slider-component";
|
||||
|
||||
import "react-before-after-slider-component/dist/build.css";
|
||||
|
||||
<ReactBeforeSliderComponent
|
||||
firstImage={{
|
||||
id: 1,
|
||||
imageUrl: useBaseUrl("img/screen_flow_dark.jpg"),
|
||||
}}
|
||||
secondImage={{
|
||||
id: 2,
|
||||
imageUrl: useBaseUrl("img/screen_flow_light.jpg"),
|
||||
}}
|
||||
/>
|
||||
|
||||
<ReactBeforeSliderComponent
|
||||
firstImage={{
|
||||
id: 1,
|
||||
imageUrl: useBaseUrl("img/screen_apps_dark.jpg"),
|
||||
}}
|
||||
secondImage={{
|
||||
id: 2,
|
||||
imageUrl: useBaseUrl("img/screen_apps_light.jpg"),
|
||||
}}
|
||||
/>
|
||||
|
||||
<ReactBeforeSliderComponent
|
||||
firstImage={{
|
||||
id: 1,
|
||||
imageUrl: useBaseUrl("img/screen_admin_dark.jpg"),
|
||||
}}
|
||||
secondImage={{
|
||||
id: 2,
|
||||
imageUrl: useBaseUrl("img/screen_admin_light.jpg"),
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -17,8 +17,8 @@ To disable these outbound connections, adjust the settings as follows:
|
||||
|
||||
To view a list of all configuration options, refer to the [Configuration](./configuration/configuration.mdx) documentation.
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs
|
||||
defaultValue="docker-compose"
|
||||
|
||||
@ -8,8 +8,8 @@ You can test upcoming authentik versions, including major new features that are
|
||||
Downgrading from the Beta is not supported. It is recommended to take a backup before upgrading, or test Beta versions on a separate install. Upgrading from Beta versions to the next release is usually possible, however also not supported.
|
||||
:::
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs
|
||||
defaultValue="docker-compose"
|
||||
|
||||
@ -17,8 +17,8 @@ All of these variables can be set to values, but you can also use a URI-like for
|
||||
|
||||
## Set your environment variables
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs groupId="platform">
|
||||
<TabItem value="docker-compose" label="Docker Compose" default>
|
||||
|
||||
@ -27,8 +27,8 @@ This installation method is for test setups and small-scale production setups.
|
||||
To download the latest `docker-compose.yml` open your terminal and navigate to the directory of your choice.
|
||||
Run the following command:
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Tabs groupId="OS">
|
||||
|
||||
@ -20,8 +20,8 @@ authentik does not support downgrading. Make sure to back up your database in ca
|
||||
|
||||
## Upgrade authentik
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import Tabs from "@theme/Tabs";
|
||||
|
||||
<Tabs groupId="platform">
|
||||
<TabItem value="docker-compose" label="Docker Compose" default>
|
||||
|
||||
@ -5,8 +5,8 @@ slug: "/releases/2024.10"
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Chrome Device Trust** <span class="badge badge--primary">Enterprise</span> <span class="badge badge--info">Preview</span>: Verify that your users are logging in from managed devices and validate the devices' compliance with company policies.
|
||||
- **FIPS/FAL3 for FedRAMP "very high" compliance** <span class="badge badge--primary">Enterprise+</span>: with support for SAML encryption and now JWE (JSON Web Encryption) support, authentik can now be configured for FIPS compliance at Federation Assurance Level (FAL) 3.
|
||||
- **Chrome Device Trust** :ak-enterprise :ak-preview : Verify that your users are logging in from managed devices and validate the devices' compliance with company policies.
|
||||
- **FIPS/FAL3 for FedRAMP "very high" compliance** :ak-enterprise : with support for SAML encryption and now JWE (JSON Web Encryption) support, authentik can now be configured for FIPS compliance at Federation Assurance Level (FAL) 3.
|
||||
- **Captcha on Identification stage**: Run a CAPTCHA process in the background while the user is entering their identification.
|
||||
- **Kerberos source**: authentik can now integrate with existing Kerberos environments by allowing users to log in with their Kerberos credentials, SPNEGO, or syncing users into authentik.
|
||||
|
||||
@ -16,7 +16,7 @@ We have no breaking changes this release!
|
||||
|
||||
## New features
|
||||
|
||||
- **Chrome Device Trust** <span class="badge badge--primary">Enterprise</span> <span class="badge badge--info">Preview</span>
|
||||
- **Chrome Device Trust** :ak-enterprise :ak-preview
|
||||
|
||||
This is a new stage for Enterprise clients that verifies the user through the Chrome Verified Access API. This stage only works with Google Chrome. You'll need to bring your own [Verified Access API instance](https://developers.google.com/chrome/verified-access/overview) via Google Cloud.
|
||||
|
||||
|
||||
@ -6,8 +6,8 @@ slug: "/releases/2024.12"
|
||||
## Highlights
|
||||
|
||||
- **Redirect stage** Conditionally redirect users to other flows and URLs.
|
||||
- **Application entitlements** <span class="badge badge--info">Preview</span> Additional granular permission configuration on an application-level basis.
|
||||
- **CloudFormation** <span class="badge badge--info">Preview</span> One-click deploy on AWS.
|
||||
- **Application entitlements** :ak-preview Additional granular permission configuration on an application-level basis.
|
||||
- **CloudFormation** :ak-preview One-click deploy on AWS.
|
||||
- **Policies in the application wizard** Configure access restriction while creating an application.
|
||||
|
||||
## Breaking changes
|
||||
@ -32,7 +32,7 @@ slug: "/releases/2024.12"
|
||||
|
||||
This new stage allows redirecting a user to another flow or external URL. This allows for dynamically choosing which flow runs depending on user attributes or other factors, or redirection to another URL.
|
||||
|
||||
- **Application entitlements** <span class="badge badge--info">Preview</span>
|
||||
- **Application entitlements** :ak-preview
|
||||
|
||||
Centrally configure permissions by granting entitlements to groups and users on an application-level basis.
|
||||
|
||||
@ -40,7 +40,7 @@ slug: "/releases/2024.12"
|
||||
|
||||
In the application creation wizard, administrators can now configure policies bindings along with the other application settings.
|
||||
|
||||
- **CloudFormation** <span class="badge badge--info">Preview</span>
|
||||
- **CloudFormation** :ak-preview
|
||||
|
||||
Deploy authentik in your own AWS environment with one click using our new [AWS CloudFormation template](../../install-config/install/aws.md).
|
||||
|
||||
|
||||
@ -5,9 +5,9 @@ slug: /releases/2024.2
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Remote Access Control** <span class="badge badge--primary">Enterprise</span> Access machines over RDP, SSH, and VNC from authentik
|
||||
- **Remote Access Control** :ak-enterprise Access machines over RDP, SSH, and VNC from authentik
|
||||
|
||||
- **Audit logging** <span class="badge badge--primary">Enterprise</span> See what fields were changed when objects are updated
|
||||
- **Audit logging** :ak-enterprise See what fields were changed when objects are updated
|
||||
|
||||
- **Session location and network binding** Increase security by preventing session theft
|
||||
|
||||
@ -102,11 +102,11 @@ slug: /releases/2024.2
|
||||
|
||||
## New features
|
||||
|
||||
- **New provider: Remote Access Control** <span class="badge badge--primary">Enterprise</span>
|
||||
- **New provider: Remote Access Control** :ak-enterprise
|
||||
|
||||
The Remote Access Control provider allows you to remotely connect to remote machines over RDP, SSH and VNC through authentik. As such, you can use the same policy engine and customization options that are possible with other providers using the same user and admin interface.
|
||||
|
||||
- **Audit logging** <span class="badge badge--primary">Enterprise</span>
|
||||
- **Audit logging** :ak-enterprise
|
||||
|
||||
authentik instances that have a valid enterprise license installed will log any changes made to models, including which fields were changed with previous and new values of the fields. The values are censored if they are sensitive (for example a password hash), however a hash of the changed value will still be logged.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user