Compare commits
2 Commits
website/in
...
server-con
| Author | SHA1 | Date | |
|---|---|---|---|
| 29a3117a94 | |||
| 66e40720c5 |
2
.github/workflows/ci-outpost.yml
vendored
2
.github/workflows/ci-outpost.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Generate API
|
- name: Generate API
|
||||||
run: make gen-client-go
|
run: make gen-client-go
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v8
|
uses: golangci/golangci-lint-action@v7
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: --timeout 5000s --verbose
|
args: --timeout 5000s --verbose
|
||||||
|
|||||||
@ -85,17 +85,18 @@ FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
|
|||||||
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
|
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
|
||||||
ENV GEOIPUPDATE_VERBOSE="1"
|
ENV GEOIPUPDATE_VERBOSE="1"
|
||||||
ENV GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID"
|
ENV GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID"
|
||||||
|
ENV GEOIPUPDATE_LICENSE_KEY_FILE="/run/secrets/GEOIPUPDATE_LICENSE_KEY"
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
||||||
--mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
|
--mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
|
||||||
mkdir -p /usr/share/GeoIP && \
|
mkdir -p /usr/share/GeoIP && \
|
||||||
/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"
|
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
||||||
|
|
||||||
# Stage 5: Download uv
|
# Stage 5: Download uv
|
||||||
FROM ghcr.io/astral-sh/uv:0.7.2 AS uv
|
FROM ghcr.io/astral-sh/uv:0.7.2 AS uv
|
||||||
# Stage 6: Base python image
|
# Stage 6: Base python image
|
||||||
FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base
|
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
|
||||||
|
|
||||||
ENV VENV_PATH="/ak-root/.venv" \
|
ENV VENV_PATH="/ak-root/.venv" \
|
||||||
PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \
|
PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \
|
||||||
|
|||||||
@ -42,4 +42,4 @@ See [SECURITY.md](SECURITY.md)
|
|||||||
|
|
||||||
## Adoption and Contributions
|
## Adoption and Contributions
|
||||||
|
|
||||||
Your organization uses authentik? We'd love to add your logo to the readme and our website! Email us @ hello@goauthentik.io or open a GitHub Issue/PR! For more information on how to contribute to authentik, please refer to our [contribution guide](https://docs.goauthentik.io/docs/developer-docs?utm_source=github).
|
Your organization uses authentik? We'd love to add your logo to the readme and our website! Email us @ hello@goauthentik.io or open a GitHub Issue/PR! For more information on how to contribute to authentik, please refer to our [CONTRIBUTING.md file](./CONTRIBUTING.md).
|
||||||
|
|||||||
@ -54,7 +54,7 @@ def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedCom
|
|||||||
return component
|
return component
|
||||||
|
|
||||||
|
|
||||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):
|
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs): # noqa: W0613
|
||||||
"""Workaround to set a default response for endpoints.
|
"""Workaround to set a default response for endpoints.
|
||||||
Workaround suggested at
|
Workaround suggested at
|
||||||
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
|
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
|
||||||
|
|||||||
@ -164,7 +164,9 @@ class BlueprintEntry:
|
|||||||
"""Get the blueprint model, with yaml tags resolved if present"""
|
"""Get the blueprint model, with yaml tags resolved if present"""
|
||||||
return str(self.tag_resolver(self.model, blueprint))
|
return str(self.tag_resolver(self.model, blueprint))
|
||||||
|
|
||||||
def get_permissions(self, blueprint: "Blueprint") -> Generator[BlueprintEntryPermission]:
|
def get_permissions(
|
||||||
|
self, blueprint: "Blueprint"
|
||||||
|
) -> Generator[BlueprintEntryPermission, None, None]:
|
||||||
"""Get permissions of this entry, with all yaml tags resolved"""
|
"""Get permissions of this entry, with all yaml tags resolved"""
|
||||||
for perm in self.permissions:
|
for perm in self.permissions:
|
||||||
yield BlueprintEntryPermission(
|
yield BlueprintEntryPermission(
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
|
||||||
|
{{ config_json|json_script:":ak-config:" }}
|
||||||
|
|
||||||
|
{{ brand_json|json_script:":ak-brand:" }}
|
||||||
|
|
||||||
|
<meta name="ak-version-family" content="{{ version_family }}">
|
||||||
|
<meta name="ak-version-subdomain" content="{{ version_subdomain }}">
|
||||||
|
<meta name="ak-build" content="{{ build }}">
|
||||||
|
<meta name="ak-base-url" content="{{ base_url }}">
|
||||||
|
<meta name="ak-base-url-rel" content="{{ base_url_rel }}">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.authentik = {
|
window.authentik = {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
"""Interface views"""
|
"""Interface views"""
|
||||||
|
|
||||||
from json import dumps
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
@ -46,14 +45,19 @@ class InterfaceView(TemplateView):
|
|||||||
"""Base interface view"""
|
"""Base interface view"""
|
||||||
|
|
||||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
kwargs["config_json"] = dumps(ConfigView(request=Request(self.request)).get_config().data)
|
"""Add common context data to all interface views"""
|
||||||
kwargs["brand_json"] = dumps(CurrentBrandSerializer(self.request.brand).data)
|
|
||||||
|
kwargs["config_json"] = ConfigView(request=Request(self.request)).get_config().data
|
||||||
|
kwargs["brand_json"] = CurrentBrandSerializer(self.request.brand).data
|
||||||
|
|
||||||
kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
|
kwargs["version_family"] = f"{LOCAL_VERSION.major}.{LOCAL_VERSION.minor}"
|
||||||
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"
|
kwargs["version_subdomain"] = f"version-{LOCAL_VERSION.major}-{LOCAL_VERSION.minor}"
|
||||||
|
|
||||||
kwargs["build"] = get_build_hash()
|
kwargs["build"] = get_build_hash()
|
||||||
kwargs["url_kwargs"] = self.kwargs
|
kwargs["url_kwargs"] = self.kwargs
|
||||||
kwargs["base_url"] = self.request.build_absolute_uri(CONFIG.get("web.path", "/"))
|
kwargs["base_url"] = self.request.build_absolute_uri(CONFIG.get("web.path", "/"))
|
||||||
kwargs["base_url_rel"] = CONFIG.get("web.path", "/")
|
kwargs["base_url_rel"] = CONFIG.get("web.path", "/")
|
||||||
|
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class LogEventSerializer(PassiveSerializer):
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def capture_logs(log_default_output=True) -> Generator[list[LogEvent]]:
|
def capture_logs(log_default_output=True) -> Generator[list[LogEvent], None, None]:
|
||||||
"""Capture log entries created"""
|
"""Capture log entries created"""
|
||||||
logs = []
|
logs = []
|
||||||
cap = LogCapture()
|
cap = LogCapture()
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class PropertyMappingManager:
|
|||||||
request: HttpRequest | None,
|
request: HttpRequest | None,
|
||||||
return_mapping: bool = False,
|
return_mapping: bool = False,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Generator[tuple[dict, PropertyMapping]]:
|
) -> Generator[tuple[dict, PropertyMapping], None]:
|
||||||
"""Iterate over all mappings that were pre-compiled and
|
"""Iterate over all mappings that were pre-compiled and
|
||||||
execute all of them with the given context"""
|
execute all of them with the given context"""
|
||||||
if not self.__has_compiled:
|
if not self.__has_compiled:
|
||||||
|
|||||||
@ -199,7 +199,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
|
|||||||
chunk_size = len(ops)
|
chunk_size = len(ops)
|
||||||
if len(ops) < 1:
|
if len(ops) < 1:
|
||||||
return
|
return
|
||||||
for chunk in batched(ops, chunk_size, strict=False):
|
for chunk in batched(ops, chunk_size):
|
||||||
req = PatchRequest(Operations=list(chunk))
|
req = PatchRequest(Operations=list(chunk))
|
||||||
self._request(
|
self._request(
|
||||||
"PATCH",
|
"PATCH",
|
||||||
|
|||||||
8
go.mod
8
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
github.com/jellydator/ttlcache/v3 v3.3.0
|
github.com/jellydator/ttlcache/v3 v3.3.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
||||||
github.com/pires/go-proxyproto v0.8.1
|
github.com/pires/go-proxyproto v0.8.0
|
||||||
github.com/prometheus/client_golang v1.22.0
|
github.com/prometheus/client_golang v1.22.0
|
||||||
github.com/redis/go-redis/v9 v9.8.0
|
github.com/redis/go-redis/v9 v9.8.0
|
||||||
github.com/sethvargo/go-envconfig v1.3.0
|
github.com/sethvargo/go-envconfig v1.3.0
|
||||||
@ -29,8 +29,8 @@ require (
|
|||||||
github.com/wwt/guac v1.3.2
|
github.com/wwt/guac v1.3.2
|
||||||
goauthentik.io/api/v3 v3.2025040.1
|
goauthentik.io/api/v3 v3.2025040.1
|
||||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||||
golang.org/x/oauth2 v0.30.0
|
golang.org/x/oauth2 v0.29.0
|
||||||
golang.org/x/sync v0.14.0
|
golang.org/x/sync v0.13.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
||||||
)
|
)
|
||||||
@ -75,7 +75,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.36.0 // indirect
|
golang.org/x/crypto v0.36.0 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
golang.org/x/text v0.24.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.5 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // 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/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 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||||
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0=
|
||||||
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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-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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
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-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-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-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-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.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-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-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.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.13.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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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.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.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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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.
Binary file not shown.
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",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.6",
|
"version": "1.0.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@goauthentik/docusaurus-config",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.6",
|
"version": "1.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deepmerge-ts": "^7.1.5",
|
"deepmerge-ts": "^7.1.5",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@goauthentik/docusaurus-config",
|
"name": "@goauthentik/docusaurus-config",
|
||||||
"version": "1.0.6",
|
"version": "1.0.5",
|
||||||
"description": "authentik's Docusaurus config",
|
"description": "authentik's Docusaurus config",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ name = "authentik"
|
|||||||
version = "2025.4.0"
|
version = "2025.4.0"
|
||||||
description = ""
|
description = ""
|
||||||
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
|
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
|
||||||
requires-python = "==3.13.*"
|
requires-python = "==3.12.*"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2-cffi",
|
"argon2-cffi",
|
||||||
"celery",
|
"celery",
|
||||||
@ -52,7 +52,7 @@ dependencies = [
|
|||||||
"pydantic-scim",
|
"pydantic-scim",
|
||||||
"pyjwt",
|
"pyjwt",
|
||||||
"pyrad",
|
"pyrad",
|
||||||
"python-kadmin-rs",
|
"python-kadmin-rs ==0.6.0",
|
||||||
"pyyaml",
|
"pyyaml",
|
||||||
"requests-oauthlib",
|
"requests-oauthlib",
|
||||||
"scim2-filter-parser",
|
"scim2-filter-parser",
|
||||||
@ -70,7 +70,7 @@ dependencies = [
|
|||||||
"watchdog",
|
"watchdog",
|
||||||
"webauthn",
|
"webauthn",
|
||||||
"wsproto",
|
"wsproto",
|
||||||
"xmlsec",
|
"xmlsec <= 1.3.14",
|
||||||
"zxcvbn",
|
"zxcvbn",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -101,18 +101,6 @@ dev = [
|
|||||||
"selenium",
|
"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]
|
[tool.uv.sources]
|
||||||
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch = "authentik-fixes" }
|
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch = "authentik-fixes" }
|
||||||
opencontainers = { git = "https://github.com/BeryJu/oci-python", rev = "c791b19056769cd67957322806809ab70f5bead8" }
|
opencontainers = { git = "https://github.com/BeryJu/oci-python", rev = "c791b19056769cd67957322806809ab70f5bead8" }
|
||||||
@ -155,12 +143,12 @@ ignore-words = ".github/codespell-words.txt"
|
|||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 100
|
line-length = 100
|
||||||
target-version = ['py313']
|
target-version = ['py312']
|
||||||
exclude = 'node_modules'
|
exclude = 'node_modules'
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 100
|
line-length = 100
|
||||||
target-version = "py313"
|
target-version = "py312"
|
||||||
exclude = ["**/migrations/**", "**/node_modules/**"]
|
exclude = ["**/migrations/**", "**/node_modules/**"]
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
services:
|
services:
|
||||||
chrome:
|
chrome:
|
||||||
image: docker.io/selenium/standalone-chrome:136.0
|
image: docker.io/selenium/standalone-chrome:122.0
|
||||||
volumes:
|
volumes:
|
||||||
- /dev/shm:/dev/shm
|
- /dev/shm:/dev/shm
|
||||||
network_mode: host
|
network_mode: host
|
||||||
restart: always
|
restart: always
|
||||||
mailpit:
|
mailpit:
|
||||||
image: docker.io/axllent/mailpit:v1.24.2
|
image: docker.io/axllent/mailpit:v1.6.5
|
||||||
ports:
|
ports:
|
||||||
- 1025:1025
|
- 1025:1025
|
||||||
- 8025:8025
|
- 8025:8025
|
||||||
|
|||||||
@ -26,7 +26,6 @@ from selenium import webdriver
|
|||||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException, WebDriverException
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException, WebDriverException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.common.keys import Keys
|
from selenium.webdriver.common.keys import Keys
|
||||||
from selenium.webdriver.remote.command import Command
|
|
||||||
from selenium.webdriver.remote.webdriver import WebDriver
|
from selenium.webdriver.remote.webdriver import WebDriver
|
||||||
from selenium.webdriver.remote.webelement import WebElement
|
from selenium.webdriver.remote.webelement import WebElement
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
@ -198,12 +197,7 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
|
|||||||
super().tearDown()
|
super().tearDown()
|
||||||
if IS_CI:
|
if IS_CI:
|
||||||
print("::group::Browser logs")
|
print("::group::Browser logs")
|
||||||
# Very verbose way to get browser logs
|
for line in self.driver.get_log("browser"):
|
||||||
# https://github.com/SeleniumHQ/selenium/pull/15641
|
|
||||||
# for some reason this removes the `get_log` API from Remote Webdriver
|
|
||||||
# and only keeps it on the local Chrome web driver, even when using
|
|
||||||
# a remote chrome driver...? (nvm the fact this was released as a minor version)
|
|
||||||
for line in self.driver.execute(Command.GET_LOG, {"type": "browser"})["value"]:
|
|
||||||
print(line["message"])
|
print(line["message"])
|
||||||
if IS_CI:
|
if IS_CI:
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
9
web/package-lock.json
generated
9
web/package-lock.json
generated
@ -9472,9 +9472,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001716",
|
"version": "1.0.30001667",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001716.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz",
|
||||||
"integrity": "sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==",
|
"integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9489,8 +9489,7 @@
|
|||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"license": "CC-BY-4.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/ccount": {
|
"node_modules/ccount": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -33,7 +33,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
|||||||
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
|
||||||
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
||||||
let build: string | TemplateResult = msg("Release");
|
let build: string | TemplateResult = msg("Release");
|
||||||
if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
if (ServerContext.config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||||
build = msg("Development");
|
build = msg("Development");
|
||||||
} else if (version.buildHash !== "") {
|
} else if (version.buildHash !== "") {
|
||||||
build = html`<a
|
build = html`<a
|
||||||
@ -58,10 +58,12 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderModal() {
|
renderModal() {
|
||||||
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||||
|
|
||||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||||
product += ` ${msg("Enterprise")}`;
|
product += ` ${msg("Enterprise")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<div
|
return html`<div
|
||||||
class="pf-c-backdrop"
|
class="pf-c-backdrop"
|
||||||
@click=${(e: PointerEvent) => {
|
@click=${(e: PointerEvent) => {
|
||||||
|
|||||||
@ -6,7 +6,8 @@ import {
|
|||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
EVENT_SIDEBAR_TOGGLE,
|
EVENT_SIDEBAR_TOGGLE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
|
||||||
@ -167,15 +168,21 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
configureSentry(true);
|
tryInitializeSentry(ServerContext.config);
|
||||||
this.user = await me();
|
this.user = await me();
|
||||||
|
|
||||||
|
setSentryPII(this.user.user);
|
||||||
|
|
||||||
const canAccessAdmin =
|
const canAccessAdmin =
|
||||||
this.user.user.isSuperuser ||
|
this.user.user.isSuperuser ||
|
||||||
// TODO: somehow add `access_admin_interface` to the API schema
|
// TODO: somehow add `access_admin_interface` to the API schema
|
||||||
this.user.user.systemPermissions.includes("access_admin_interface");
|
this.user.user.systemPermissions.includes("access_admin_interface");
|
||||||
|
|
||||||
if (!canAccessAdmin && this.user.user.pk > 0) {
|
if (!canAccessAdmin && this.user.user.pk > 0) {
|
||||||
|
console.debug(
|
||||||
|
"authentik/admin: User does not have access to admin interface. Redirecting...",
|
||||||
|
);
|
||||||
|
|
||||||
window.location.assign("/if/user/");
|
window.location.assign("/if/user/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,7 +113,8 @@ export class ApplicationViewPage extends AKElement {
|
|||||||
|
|
||||||
renderApp(): TemplateResult {
|
renderApp(): TemplateResult {
|
||||||
if (!this.application) {
|
if (!this.application) {
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html`<ak-tabs>
|
return html`<ak-tabs>
|
||||||
${this.missingOutpost
|
${this.missingOutpost
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/components/ak-toggle-group";
|
import "@goauthentik/components/ak-toggle-group";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
|
||||||
import "@goauthentik/elements/buttons/TokenCopyButton";
|
import "@goauthentik/elements/buttons/TokenCopyButton";
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import { groupBy } from "@goauthentik/common/utils";
|
import { groupBy } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
|
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { BasePropertyMappingForm } from "@goauthentik/admin/property-mappings/BasePropertyMappingForm";
|
import { BasePropertyMappingForm } from "@goauthentik/admin/property-mappings/BasePropertyMappingForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { docLink } from "@goauthentik/common/global";
|
import { docLink } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export class ProviderViewPage extends AKElement {
|
|||||||
|
|
||||||
renderProvider(): TemplateResult {
|
renderProvider(): TemplateResult {
|
||||||
if (!this.provider) {
|
if (!this.provider) {
|
||||||
return html`<ak-empty-state loading ?fullHeight=${true}></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true} ?fullHeight=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
switch (this.provider?.component) {
|
switch (this.provider?.component) {
|
||||||
case "ak-provider-saml-form":
|
case "ak-provider-saml-form":
|
||||||
|
|||||||
@ -432,7 +432,7 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
${this.preview
|
${this.preview
|
||||||
? html`<pre>${JSON.stringify(this.preview?.preview, null, 4)}</pre>`
|
? html`<pre>${JSON.stringify(this.preview?.preview, null, 4)}</pre>`
|
||||||
: html` <ak-empty-state loading></ak-empty-state> `}
|
: html` <ak-empty-state ?loading=${true}></ak-empty-state> `}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|||||||
@ -502,7 +502,7 @@ export class SAMLProviderViewPage extends AKElement {
|
|||||||
|
|
||||||
renderTabPreview(): TemplateResult {
|
renderTabPreview(): TemplateResult {
|
||||||
if (!this.preview) {
|
if (!this.preview) {
|
||||||
return html`<ak-empty-state loading></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html` <div
|
return html` <div
|
||||||
class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter"
|
class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter"
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export class SourceViewPage extends AKElement {
|
|||||||
|
|
||||||
renderSource(): TemplateResult {
|
renderSource(): TemplateResult {
|
||||||
if (!this.source) {
|
if (!this.source) {
|
||||||
return html`<ak-empty-state loading ?fullHeight=${true}></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true} ?fullHeight=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
switch (this.source?.component) {
|
switch (this.source?.component) {
|
||||||
case "ak-source-kerberos-form":
|
case "ak-source-kerberos-form":
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||||
import "@goauthentik/components/ak-switch-input";
|
import "@goauthentik/components/ak-switch-input";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import "@goauthentik/components/ak-textarea-input";
|
import "@goauthentik/components/ak-textarea-input";
|
||||||
@ -60,8 +61,9 @@ export class KerberosSourceForm extends WithCapabilitiesConfig(BaseSourceForm<Ke
|
|||||||
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
|
kerberosSourceRequest: data as unknown as KerberosSourceRequest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const c = await config();
|
const { capabilities } = ServerContext.config;
|
||||||
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
|
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||||
import "@goauthentik/components/ak-radio-input";
|
import "@goauthentik/components/ak-radio-input";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
@ -85,8 +86,9 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
|
|||||||
oAuthSourceRequest: data as unknown as OAuthSourceRequest,
|
oAuthSourceRequest: data as unknown as OAuthSourceRequest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const c = await config();
|
const { capabilities } = ServerContext.config;
|
||||||
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
|
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
|||||||
@ -6,7 +6,8 @@ import {
|
|||||||
GroupMatchingModeToLabel,
|
GroupMatchingModeToLabel,
|
||||||
UserMatchingModeToLabel,
|
UserMatchingModeToLabel,
|
||||||
} from "@goauthentik/admin/sources/oauth/utils";
|
} from "@goauthentik/admin/sources/oauth/utils";
|
||||||
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context.js";
|
||||||
import {
|
import {
|
||||||
CapabilitiesEnum,
|
CapabilitiesEnum,
|
||||||
WithCapabilitiesConfig,
|
WithCapabilitiesConfig,
|
||||||
@ -61,8 +62,9 @@ export class SAMLSourceForm extends WithCapabilitiesConfig(BaseSourceForm<SAMLSo
|
|||||||
sAMLSourceRequest: data,
|
sAMLSourceRequest: data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const c = await config();
|
const { capabilities } = ServerContext.config;
|
||||||
if (c.capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
|
||||||
|
if (capabilities.includes(CapabilitiesEnum.CanSaveMedia)) {
|
||||||
const icon = this.getFormFiles()["icon"];
|
const icon = this.getFormFiles()["icon"];
|
||||||
if (icon || this.clearIcon) {
|
if (icon || this.clearIcon) {
|
||||||
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import { Form } from "@goauthentik/elements/forms/Form";
|
import { Form } from "@goauthentik/elements/forms/Form";
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export class UserImpersonateForm extends Form<ImpersonationRequest> {
|
|||||||
impersonationRequest: data,
|
impersonationRequest: data,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
window.location.href = globalAK().api.base;
|
window.location.href = ServerContext.baseURL;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,22 +5,14 @@ import {
|
|||||||
LoggingMiddleware,
|
LoggingMiddleware,
|
||||||
} from "@goauthentik/common/api/middleware";
|
} from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
|
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
|
|
||||||
import { Config, Configuration, CoreApi, CurrentBrand, RootApi } from "@goauthentik/api";
|
import { Configuration, CurrentBrand } from "@goauthentik/api";
|
||||||
|
|
||||||
// HACK: Workaround for ESBuild not being able to hoist import statement across entrypoints.
|
// HACK: Workaround for ESBuild not being able to hoist import statement across entrypoints.
|
||||||
// This can be removed after ESBuild uses a single build context for all entrypoints.
|
// This can be removed after ESBuild uses a single build context for all entrypoints.
|
||||||
export { CSRFHeaderName };
|
export { CSRFHeaderName };
|
||||||
|
|
||||||
let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
|
|
||||||
export function config(): Promise<Config> {
|
|
||||||
if (!globalConfigPromise) {
|
|
||||||
globalConfigPromise = new RootApi(DEFAULT_CONFIG).rootConfigRetrieve();
|
|
||||||
}
|
|
||||||
return globalConfigPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function brandSetFavicon(brand: CurrentBrand) {
|
export function brandSetFavicon(brand: CurrentBrand) {
|
||||||
/**
|
/**
|
||||||
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
|
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
|
||||||
@ -52,35 +44,22 @@ export function brandSetLocale(brand: CurrentBrand) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let globalBrandPromise: Promise<CurrentBrand> | undefined = Promise.resolve(globalAK().brand);
|
|
||||||
export function brand(): Promise<CurrentBrand> {
|
|
||||||
if (!globalBrandPromise) {
|
|
||||||
globalBrandPromise = new CoreApi(DEFAULT_CONFIG)
|
|
||||||
.coreBrandsCurrentRetrieve()
|
|
||||||
.then((brand) => {
|
|
||||||
brandSetFavicon(brand);
|
|
||||||
brandSetLocale(brand);
|
|
||||||
return brand;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return globalBrandPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getMetaContent(key: string): string {
|
export function getMetaContent(key: string): string {
|
||||||
const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
|
const metaEl = document.querySelector<HTMLMetaElement>(`meta[name=${key}]`);
|
||||||
if (!metaEl) return "";
|
if (!metaEl) return "";
|
||||||
|
|
||||||
return metaEl.content;
|
return metaEl.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_CONFIG = new Configuration({
|
export const DEFAULT_CONFIG = new Configuration({
|
||||||
basePath: `${globalAK().api.base}api/v3`,
|
basePath: `${ServerContext.baseURL}api/v3`,
|
||||||
headers: {
|
headers: {
|
||||||
"sentry-trace": getMetaContent("sentry-trace"),
|
"sentry-trace": ServerContext.sentryTrace,
|
||||||
},
|
},
|
||||||
middleware: [
|
middleware: [
|
||||||
new CSRFMiddleware(),
|
new CSRFMiddleware(),
|
||||||
new EventMiddleware(),
|
new EventMiddleware(),
|
||||||
new LoggingMiddleware(globalAK().brand),
|
new LoggingMiddleware(ServerContext.brand),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
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,89 +1,131 @@
|
|||||||
import { config } from "@goauthentik/common/api/config";
|
|
||||||
import { VERSION } from "@goauthentik/common/constants";
|
import { VERSION } from "@goauthentik/common/constants";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { RouteInterfaceName, readInterfaceRouteParam } from "@goauthentik/elements/router/utils";
|
||||||
import { readInterfaceRouteParam } from "@goauthentik/elements/router/utils";
|
import { BrowserOptions, browserTracingIntegration, init, setTag, setUser } from "@sentry/browser";
|
||||||
import {
|
|
||||||
ErrorEvent,
|
|
||||||
EventHint,
|
|
||||||
browserTracingIntegration,
|
|
||||||
init,
|
|
||||||
setTag,
|
|
||||||
setUser,
|
|
||||||
} from "@sentry/browser";
|
|
||||||
|
|
||||||
import { CapabilitiesEnum, Config, ResponseError } from "@goauthentik/api";
|
import { CapabilitiesEnum, Config, ResponseError, UserSelf } from "@goauthentik/api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic error that can be thrown without triggering Sentry's reporting.
|
* A generic error that can be thrown without triggering Sentry's reporting.
|
||||||
|
*
|
||||||
|
* @category Sentry
|
||||||
*/
|
*/
|
||||||
export class SentryIgnoredError extends Error {}
|
export class SentryIgnoredError extends Error {}
|
||||||
|
|
||||||
export const TAG_SENTRY_COMPONENT = "authentik.component";
|
/**
|
||||||
export const TAG_SENTRY_CAPABILITIES = "authentik.capabilities";
|
* Attempt initializing Spotlight.
|
||||||
|
*
|
||||||
export async function configureSentry(canDoPpi = false): Promise<Config> {
|
* @see {@link https://spotlightjs.com/ Spotlight}
|
||||||
const cfg = await config();
|
* @category Sentry
|
||||||
|
*/
|
||||||
if (cfg.errorReporting.enabled) {
|
export async function tryInitializingSpotlight() {
|
||||||
init({
|
return import("@spotlightjs/spotlight").then((Spotlight) =>
|
||||||
dsn: cfg.errorReporting.sentryDsn,
|
Spotlight.init({ injectImmediately: true }),
|
||||||
ignoreErrors: [
|
);
|
||||||
/network/gi,
|
}
|
||||||
/fetch/gi,
|
|
||||||
/module/gi,
|
/**
|
||||||
// Error on edge on ios,
|
* Default Sentry options for the browser.
|
||||||
// https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
|
*
|
||||||
/instantSearchSDKJSBridgeClearHighlight/gi,
|
* @category Sentry
|
||||||
// Seems to be an issue in Safari and Firefox
|
*/
|
||||||
/MutationObserver.observe/gi,
|
const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
||||||
/NS_ERROR_FAILURE/gi,
|
ignoreErrors: [
|
||||||
],
|
/network/gi,
|
||||||
release: `authentik@${VERSION}`,
|
/fetch/gi,
|
||||||
integrations: [
|
/module/gi,
|
||||||
browserTracingIntegration({
|
// Error on edge on ios,
|
||||||
shouldCreateSpanForRequest: (url: string) => {
|
// https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
|
||||||
return url.startsWith(window.location.host);
|
/instantSearchSDKJSBridgeClearHighlight/gi,
|
||||||
},
|
// Seems to be an issue in Safari and Firefox
|
||||||
}),
|
/MutationObserver.observe/gi,
|
||||||
],
|
/NS_ERROR_FAILURE/gi,
|
||||||
tracesSampleRate: cfg.errorReporting.tracesSampleRate,
|
],
|
||||||
environment: cfg.errorReporting.environment,
|
release: `authentik@${VERSION}`,
|
||||||
beforeSend: (
|
integrations: [
|
||||||
event: ErrorEvent,
|
browserTracingIntegration({
|
||||||
hint: EventHint,
|
shouldCreateSpanForRequest: (url: string) => {
|
||||||
): ErrorEvent | PromiseLike<ErrorEvent | null> | null => {
|
return url.startsWith(window.location.host);
|
||||||
if (!hint) {
|
},
|
||||||
return event;
|
}),
|
||||||
}
|
],
|
||||||
if (hint.originalException instanceof SentryIgnoredError) {
|
beforeSend: (event, hint) => {
|
||||||
return null;
|
if (!hint) {
|
||||||
}
|
return event;
|
||||||
if (
|
}
|
||||||
hint.originalException instanceof ResponseError ||
|
if (hint.originalException instanceof SentryIgnoredError) {
|
||||||
hint.originalException instanceof DOMException
|
return null;
|
||||||
) {
|
}
|
||||||
return null;
|
if (
|
||||||
}
|
hint.originalException instanceof ResponseError ||
|
||||||
return event;
|
hint.originalException instanceof DOMException
|
||||||
},
|
) {
|
||||||
});
|
return null;
|
||||||
setTag(TAG_SENTRY_CAPABILITIES, cfg.capabilities.join(","));
|
}
|
||||||
if (window.location.pathname.includes("if/")) {
|
return event;
|
||||||
setTag(TAG_SENTRY_COMPONENT, `web/${readInterfaceRouteParam()}`);
|
},
|
||||||
}
|
} as const satisfies BrowserOptions;
|
||||||
if (cfg.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
|
||||||
const Spotlight = await import("@spotlightjs/spotlight");
|
/**
|
||||||
|
* Include the given user in Sentry events.
|
||||||
Spotlight.init({ injectImmediately: true });
|
*
|
||||||
}
|
* @category Sentry
|
||||||
if (cfg.errorReporting.sendPii && canDoPpi) {
|
*/
|
||||||
me().then((user) => {
|
export function setSentryPII(user: UserSelf): void {
|
||||||
setUser({ email: user.user.email });
|
console.debug("authentik/sentry: PII enabled.");
|
||||||
console.debug("authentik/config: Sentry with PII enabled.");
|
|
||||||
});
|
setUser({ email: user.email });
|
||||||
} else {
|
}
|
||||||
console.debug("authentik/config: Sentry enabled.");
|
|
||||||
}
|
/**
|
||||||
}
|
* Include the given capabilities in Sentry events.
|
||||||
return cfg;
|
*
|
||||||
|
* @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);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
web/src/common/server-context.ts
Normal file
116
web/src/common/server-context.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* @file Server context singleton.
|
||||||
|
*/
|
||||||
|
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
|
||||||
|
|
||||||
|
function readMetaElement(key: string, fallback: string = ""): string {
|
||||||
|
const metaElement = document.querySelector<HTMLMetaElement>(`meta[name="${key}"]`);
|
||||||
|
const value = metaElement?.getAttribute("content") || fallback;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ServerContextValue {
|
||||||
|
/**
|
||||||
|
* Server-injected authentik configuration.
|
||||||
|
*/
|
||||||
|
config: Readonly<Config>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brand information used to customize the UI.
|
||||||
|
*/
|
||||||
|
brand: Readonly<CurrentBrand>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A semantic versioning string representing the current version of authentik.
|
||||||
|
*/
|
||||||
|
versionFamily: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subdomain-compatible version string representing the current version of authentik.
|
||||||
|
*/
|
||||||
|
versionSubdomain: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A build hash string representing the current build of authentik.
|
||||||
|
*/
|
||||||
|
build: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base URL of the authentik instance.
|
||||||
|
*/
|
||||||
|
baseURL: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The relative base URL of the authentik instance.
|
||||||
|
*/
|
||||||
|
baseURLRelative: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The layout of the flow, if any.
|
||||||
|
*/
|
||||||
|
flowLayout: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Sentry trace ID for the current request.
|
||||||
|
*/
|
||||||
|
sentryTrace: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the server context from the DOM.
|
||||||
|
*/
|
||||||
|
export function refreshServerContext(): Readonly<ServerContextValue> {
|
||||||
|
const configElement = document.getElementById(":ak-config:");
|
||||||
|
|
||||||
|
const config = configElement?.textContent
|
||||||
|
? ConfigFromJSON(JSON.parse(configElement.textContent))
|
||||||
|
: ConfigFromJSON({
|
||||||
|
capabilities: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const brandElement = document.getElementById(":ak-brand:");
|
||||||
|
|
||||||
|
const brand = brandElement?.textContent
|
||||||
|
? CurrentBrandFromJSON(JSON.parse(brandElement.textContent))
|
||||||
|
: CurrentBrandFromJSON({
|
||||||
|
ui_footer_links: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const apiBaseURL = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||||
|
|
||||||
|
const value: ServerContextValue = {
|
||||||
|
sentryTrace: readMetaElement("sentry-trace"),
|
||||||
|
baseURL: readMetaElement("ak-base-url") || apiBaseURL.toString(),
|
||||||
|
baseURLRelative: readMetaElement("ak-base-url-rel"),
|
||||||
|
|
||||||
|
versionFamily: readMetaElement("ak-version-family"),
|
||||||
|
versionSubdomain: readMetaElement("ak-version-subdomain"),
|
||||||
|
|
||||||
|
build: readMetaElement("ak-build"),
|
||||||
|
|
||||||
|
flowLayout: readMetaElement("ak-flow-layout"),
|
||||||
|
config,
|
||||||
|
brand,
|
||||||
|
};
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server injected values used to configure application.
|
||||||
|
*
|
||||||
|
* @singleton
|
||||||
|
*/
|
||||||
|
export const ServerContext = refreshServerContext();
|
||||||
|
|
||||||
|
export function docLink(path: string): string {
|
||||||
|
const { build, versionSubdomain } = ServerContext;
|
||||||
|
|
||||||
|
// Default case or beta build which should always point to latest
|
||||||
|
if (build) {
|
||||||
|
return new URL(path, "https://goauthentik.io").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new URL(path, `https://${versionSubdomain}.goauthentik.io`).toString();
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
|
import { EVENT_MESSAGE, EVENT_WS_MESSAGE } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
|
|
||||||
@ -22,11 +22,14 @@ export class WebsocketClient {
|
|||||||
|
|
||||||
connect(): void {
|
connect(): void {
|
||||||
if (navigator.webdriver) return;
|
if (navigator.webdriver) return;
|
||||||
const apiURL = new URL(globalAK().api.base);
|
|
||||||
const wsUrl = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
|
const apiURL = new URL(ServerContext.baseURL);
|
||||||
this.messageSocket = new WebSocket(wsUrl);
|
|
||||||
|
const wsURL = `${window.location.protocol.replace("http", "ws")}//${apiURL.host}${apiURL.pathname}ws/client/`;
|
||||||
|
|
||||||
|
this.messageSocket = new WebSocket(wsURL);
|
||||||
this.messageSocket.addEventListener("open", () => {
|
this.messageSocket.addEventListener("open", () => {
|
||||||
console.debug(`authentik/ws: connected to ${wsUrl}`);
|
console.debug(`authentik/ws: connected to ${wsURL}`);
|
||||||
this.retryDelay = 200;
|
this.retryDelay = 200;
|
||||||
});
|
});
|
||||||
this.messageSocket.addEventListener("close", (e) => {
|
this.messageSocket.addEventListener("close", (e) => {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import {
|
|||||||
EVENT_API_DRAWER_TOGGLE,
|
EVENT_API_DRAWER_TOGGLE,
|
||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
|
import { UIConfig, UserDisplay, uiConfig } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -146,7 +146,7 @@ export class NavigationButtons extends AKElement {
|
|||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-plain"
|
class="pf-c-button pf-m-plain"
|
||||||
type="button"
|
type="button"
|
||||||
href="${globalAK().api.base}if/user/#/settings"
|
href="${ServerContext.baseURL}if/user/#/settings"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Settings")}>
|
<pf-tooltip position="top" content=${msg("Settings")}>
|
||||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||||
@ -200,7 +200,7 @@ export class NavigationButtons extends AKElement {
|
|||||||
${this.renderSettings()}
|
${this.renderSettings()}
|
||||||
<div class="pf-c-page__header-tools-item">
|
<div class="pf-c-page__header-tools-item">
|
||||||
<a
|
<a
|
||||||
href="${globalAK().api.base}flows/-/default/invalidation/"
|
href="${ServerContext.baseURL}flows/-/default/invalidation/"
|
||||||
class="pf-c-button pf-m-plain"
|
class="pf-c-button pf-m-plain"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Sign out")}>
|
<pf-tooltip position="top" content=${msg("Sign out")}>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import {
|
import {
|
||||||
StyleSheetInit,
|
StyleSheetInit,
|
||||||
StyleSheetParent,
|
StyleSheetParent,
|
||||||
@ -82,7 +82,7 @@ export class AKElement extends LitElement implements ThemedElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const { brand } = globalAK();
|
const { brand } = ServerContext;
|
||||||
|
|
||||||
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
|
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
|
||||||
this.activeTheme = resolveUITheme(brand?.uiTheme);
|
this.activeTheme = resolveUITheme(brand?.uiTheme);
|
||||||
|
|||||||
@ -83,7 +83,7 @@ export class Diagram extends AKElement {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!this.diagram) {
|
if (!this.diagram) {
|
||||||
return html`<ak-empty-state loading></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html`${until(
|
return html`${until(
|
||||||
mermaid.render("graph", this.diagram).then((r) => {
|
mermaid.render("graph", this.diagram).then((r) => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { ThemedElement } from "@goauthentik/common/theme";
|
import { ThemedElement } from "@goauthentik/common/theme";
|
||||||
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
|
import { authentikConfigContext } from "@goauthentik/elements/AuthentikContexts";
|
||||||
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
|
import type { ReactiveElementHost } from "@goauthentik/elements/types.js";
|
||||||
@ -23,8 +23,8 @@ export class ConfigContextController implements ReactiveController {
|
|||||||
initialValue: undefined,
|
initialValue: undefined,
|
||||||
});
|
});
|
||||||
// Pre-hydrate from template-embedded config
|
// Pre-hydrate from template-embedded config
|
||||||
this.context.setValue(globalAK().config);
|
this.context.setValue(ServerContext.config);
|
||||||
this.host.config = globalAK().config;
|
this.host.config = ServerContext.config;
|
||||||
this.fetch = this.fetch.bind(this);
|
this.fetch = this.fetch.bind(this);
|
||||||
this.fetch();
|
this.fetch();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,10 @@ import {
|
|||||||
EVENT_WS_MESSAGE,
|
EVENT_WS_MESSAGE,
|
||||||
TITLE_DEFAULT,
|
TITLE_DEFAULT,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { UIConfig, UserDisplay, getConfigForUser } from "@goauthentik/common/ui/config";
|
import { getConfigForUser } from "@goauthentik/common/ui/config";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
|
import { UIConfig, UserDisplay } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import "@goauthentik/components/ak-nav-buttons";
|
import "@goauthentik/components/ak-nav-buttons";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -404,7 +405,7 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
|
|||||||
<ak-nav-buttons .uiConfig=${this.uiConfig} .me=${this.session}>
|
<ak-nav-buttons .uiConfig=${this.uiConfig} .me=${this.session}>
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
||||||
href="${globalAK().api.base}if/user/"
|
href="${ServerContext.baseURL}if/user/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("User interface")}
|
${msg("User interface")}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
|
|
||||||
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
|
import { LOCALES as RAW_LOCALES, enLocale } from "./definitions";
|
||||||
import { AkLocale } from "./types";
|
import { AkLocale } from "./types";
|
||||||
|
|
||||||
@ -51,7 +49,7 @@ export function autoDetectLanguage(userReq = TOMBSTONE, brandReq = TOMBSTONE): s
|
|||||||
userReq,
|
userReq,
|
||||||
window.navigator?.language ?? TOMBSTONE,
|
window.navigator?.language ?? TOMBSTONE,
|
||||||
brandReq,
|
brandReq,
|
||||||
globalAK()?.locale ?? TOMBSTONE,
|
document.documentElement.getAttribute("lang") ?? TOMBSTONE,
|
||||||
DEFAULT_LOCALE,
|
DEFAULT_LOCALE,
|
||||||
].filter(isLocaleCandidate);
|
].filter(isLocaleCandidate);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ export class EnterpriseStatusBanner extends WithLicenseSummary(AKElement) {
|
|||||||
: "pf-m-gold"}"
|
: "pf-m-gold"}"
|
||||||
>
|
>
|
||||||
${message}
|
${message}
|
||||||
<a href="${globalAK().api.base}if/admin/#/enterprise/licenses"
|
<a href="${ServerContext.baseURL}if/admin/#/enterprise/licenses"
|
||||||
>${msg("Click here for more info.")}</a
|
>${msg("Click here for more info.")}</a
|
||||||
>
|
>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|||||||
@ -230,7 +230,9 @@ export abstract class AKChart<T> extends AKElement {
|
|||||||
<p slot="body">${pluckErrorDetail(this.error)}</p>
|
<p slot="body">${pluckErrorDetail(this.error)}</p>
|
||||||
</ak-empty-state>
|
</ak-empty-state>
|
||||||
`
|
`
|
||||||
: html`${this.chart ? html`` : html`<ak-empty-state loading></ak-empty-state>`}`}
|
: html`${this.chart
|
||||||
|
? html``
|
||||||
|
: html`<ak-empty-state ?loading="${true}"></ak-empty-state>`}`}
|
||||||
${this.centerText ? html` <span>${this.centerText}</span> ` : html``}
|
${this.centerText ? html` <span>${this.centerText}</span> ` : html``}
|
||||||
<canvas style="${this.chart === undefined ? "display: none;" : ""}"></canvas>
|
<canvas style="${this.chart === undefined ? "display: none;" : ""}"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -71,7 +71,7 @@ export abstract class ModelForm<T, PKT extends string | number> extends Form<T>
|
|||||||
|
|
||||||
renderVisible(): TemplateResult {
|
renderVisible(): TemplateResult {
|
||||||
if ((this._instancePk && !this.instance) || !this._initialDataLoad) {
|
if ((this._instancePk && !this.instance) || !this._initialDataLoad) {
|
||||||
return html`<ak-empty-state loading></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return super.renderVisible();
|
return super.renderVisible();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ export class APIDrawer extends AKElement {
|
|||||||
<h1 class="pf-c-notification-drawer__header-title">
|
<h1 class="pf-c-notification-drawer__header-title">
|
||||||
${msg("API Requests")}
|
${msg("API Requests")}
|
||||||
</h1>
|
</h1>
|
||||||
<a href="${globalAK().api.base}api/v3/" target="_blank"
|
<a href="${ServerContext.baseURL}api/v3/" target="_blank"
|
||||||
>${msg("Open API Browser")}</a
|
>${msg("Open API Browser")}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
@ -99,7 +99,7 @@ export class NotificationDrawer extends AKElement {
|
|||||||
html`
|
html`
|
||||||
<a
|
<a
|
||||||
class="pf-c-dropdown__toggle pf-m-plain"
|
class="pf-c-dropdown__toggle pf-m-plain"
|
||||||
href="${globalAK().api.base}if/admin/#/events/log/${item.event?.pk}"
|
href="${ServerContext.baseURL}if/admin/#/events/log/${item.event?.pk}"
|
||||||
>
|
>
|
||||||
<pf-tooltip position="top" content=${msg("Show details")}>
|
<pf-tooltip position="top" content=${msg("Show details")}>
|
||||||
<i class="fas fa-share-square"></i>
|
<i class="fas fa-share-square"></i>
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export class Route {
|
|||||||
if (this.callback) {
|
if (this.callback) {
|
||||||
return html`${until(
|
return html`${until(
|
||||||
this.callback(args),
|
this.callback(args),
|
||||||
html`<ak-empty-state loading></ak-empty-state>`,
|
html`<ak-empty-state ?loading=${true}></ak-empty-state>`,
|
||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
if (this.element) {
|
if (this.element) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
|
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
|
||||||
@ -45,7 +45,7 @@ export class SidebarVersion extends WithLicenseSummary(WithVersion(AKElement)) {
|
|||||||
if (!this.version || !this.licenseSummary) {
|
if (!this.version || !this.licenseSummary) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
|
let product = ServerContext.brand.brandingTitle || DefaultBrand.brandingTitle;
|
||||||
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
|
||||||
product += ` ${msg("Enterprise")}`;
|
product += ` ${msg("Enterprise")}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ export class SyncStatusCard extends AKElement {
|
|||||||
|
|
||||||
renderSyncStatus(): TemplateResult {
|
renderSyncStatus(): TemplateResult {
|
||||||
if (this.loading) {
|
if (this.loading) {
|
||||||
return html`<ak-empty-state loading></ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
|
||||||
}
|
}
|
||||||
if (!this.syncState) {
|
if (!this.syncState) {
|
||||||
return html`${msg("No sync status.")}`;
|
return html`${msg("No sync status.")}`;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ describe("ak-empty-state", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should render the default loader", async () => {
|
it("should render the default loader", async () => {
|
||||||
render(html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`);
|
render(html`<ak-empty-state ?loading=${true} header=${msg("Loading")}> </ak-empty-state>`);
|
||||||
|
|
||||||
const empty = await $("ak-empty-state").$(">>>.pf-c-empty-state__icon");
|
const empty = await $("ak-empty-state").$(">>>.pf-c-empty-state__icon");
|
||||||
await expect(empty).toExist();
|
await expect(empty).toExist();
|
||||||
|
|||||||
@ -139,7 +139,8 @@ export class UserSourceSettingsPage extends AKElement {
|
|||||||
})}
|
})}
|
||||||
`}
|
`}
|
||||||
`
|
`
|
||||||
: html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`}
|
: html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`}
|
||||||
</ul>`;
|
</ul>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
EVENT_FLOW_INSPECTOR_TOGGLE,
|
EVENT_FLOW_INSPECTOR_TOGGLE,
|
||||||
TITLE_DEFAULT,
|
TITLE_DEFAULT,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { Interface } from "@goauthentik/elements/Interface";
|
import { Interface } from "@goauthentik/elements/Interface";
|
||||||
@ -237,10 +237,12 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async firstUpdated(): Promise<void> {
|
async firstUpdated(): Promise<void> {
|
||||||
configureSentry();
|
tryInitializeSentry(ServerContext.config);
|
||||||
|
|
||||||
if (this.config?.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
if (this.config?.capabilities.includes(CapabilitiesEnum.CanDebug)) {
|
||||||
this.inspectorAvailable = true;
|
this.inspectorAvailable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
const challenge = await new FlowsApi(DEFAULT_CONFIG).flowsExecutorGet({
|
const challenge = await new FlowsApi(DEFAULT_CONFIG).flowsExecutorGet({
|
||||||
@ -481,7 +483,8 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLayout(): string {
|
getLayout(): string {
|
||||||
const prefilledFlow = globalAK()?.flow?.layout || FlowLayoutEnum.Stacked;
|
const prefilledFlow = ServerContext.flowLayout || FlowLayoutEnum.Stacked;
|
||||||
|
|
||||||
if (this.challenge) {
|
if (this.challenge) {
|
||||||
return this.challenge?.flowInfo?.layout || prefilledFlow;
|
return this.challenge?.flowInfo?.layout || prefilledFlow;
|
||||||
}
|
}
|
||||||
@ -521,7 +524,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
<img
|
<img
|
||||||
src="${themeImage(
|
src="${themeImage(
|
||||||
this.brand?.brandingLogo ??
|
this.brand?.brandingLogo ??
|
||||||
globalAK()?.brand.brandingLogo ??
|
ServerContext.brand.brandingLogo ??
|
||||||
DefaultBrand.brandingLogo,
|
DefaultBrand.brandingLogo,
|
||||||
)}"
|
)}"
|
||||||
alt="${msg("authentik Logo")}"
|
alt="${msg("authentik Logo")}"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/flow/FormStatic";
|
import "@goauthentik/flow/FormStatic";
|
||||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||||
|
|
||||||
@ -24,7 +24,8 @@ export class SessionEnd extends BaseStage<SessionEndChallenge, unknown> {
|
|||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
if (!this.challenge) {
|
if (!this.challenge) {
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html`<header class="pf-c-login__main-header">
|
return html`<header class="pf-c-login__main-header">
|
||||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||||
@ -47,7 +48,7 @@ export class SessionEnd extends BaseStage<SessionEndChallenge, unknown> {
|
|||||||
str`You've logged out of ${this.challenge.applicationName}. You can go back to the overview to launch another application, or log out of your authentik account.`,
|
str`You've logged out of ${this.challenge.applicationName}. You can go back to the overview to launch another application, or log out of your authentik account.`,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<a href="${globalAK().api.base}" class="pf-c-button pf-m-primary">
|
<a href="${ServerContext.baseURL}" class="pf-c-button pf-m-primary">
|
||||||
${msg("Go back to overview")}
|
${msg("Go back to overview")}
|
||||||
</a>
|
</a>
|
||||||
${this.challenge.invalidationFlowUrl
|
${this.challenge.invalidationFlowUrl
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { PFSize } from "@goauthentik/common/enums.js";
|
import { PFSize } from "@goauthentik/common/enums.js";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { truncateWords } from "@goauthentik/common/utils";
|
import { truncateWords } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/AppIcon";
|
import "@goauthentik/elements/AppIcon";
|
||||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||||
@ -82,8 +82,7 @@ export class LibraryApplication extends AKElement {
|
|||||||
? html`
|
? html`
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
||||||
href="${globalAK().api
|
href="${ServerContext.baseURL}if/admin/#/core/applications/${application?.slug}"
|
||||||
.base}if/admin/#/core/applications/${application?.slug}"
|
|
||||||
>
|
>
|
||||||
<i class="fas fa-edit"></i> ${msg("Edit")}
|
<i class="fas fa-edit"></i> ${msg("Edit")}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { docLink, globalAK } from "@goauthentik/common/global";
|
import { ServerContext, docLink } from "@goauthentik/common/server-context";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
import { paramURL } from "@goauthentik/elements/router/RouterOutlet";
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export class LibraryPageApplicationEmptyList extends AKElement {
|
|||||||
<a
|
<a
|
||||||
aria-disabled="false"
|
aria-disabled="false"
|
||||||
class="cta pf-c-button pf-m-secondary"
|
class="cta pf-c-button pf-m-secondary"
|
||||||
href="${globalAK().api.base}if/admin/${href}"
|
href="${ServerContext.baseURL}if/admin/${href}"
|
||||||
>${msg("Create a new application")}</a
|
>${msg("Create a new application")}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -102,7 +102,7 @@ export class LibraryPage extends AKElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loading() {
|
loading() {
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}> </ak-empty-state>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
running() {
|
running() {
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||||
EVENT_WS_MESSAGE,
|
EVENT_WS_MESSAGE,
|
||||||
} from "@goauthentik/common/constants";
|
} from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { setSentryPII, tryInitializeSentry } from "@goauthentik/common/sentry";
|
||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { UIConfig, getConfigForUser } from "@goauthentik/common/ui/config";
|
import { UIConfig, getConfigForUser } from "@goauthentik/common/ui/config";
|
||||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
import { DefaultBrand } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
@ -170,14 +170,14 @@ class UserInterfacePresentation extends AKElement {
|
|||||||
|
|
||||||
return html`<a
|
return html`<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none pf-u-display-block-on-md"
|
||||||
href="${globalAK().api.base}if/admin/"
|
href="${ServerContext.baseURL}if/admin/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("Admin interface")}
|
${msg("Admin interface")}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none-on-md pf-u-display-block"
|
class="pf-c-button pf-m-secondary pf-m-small pf-u-display-none-on-md pf-u-display-block"
|
||||||
href="${globalAK().api.base}if/admin/"
|
href="${ServerContext.baseURL}if/admin/"
|
||||||
slot="extra"
|
slot="extra"
|
||||||
>
|
>
|
||||||
${msg("Admin")}
|
${msg("Admin")}
|
||||||
@ -284,7 +284,9 @@ export class UserInterface extends AuthenticatedInterface {
|
|||||||
super();
|
super();
|
||||||
this.ws = new WebsocketClient();
|
this.ws = new WebsocketClient();
|
||||||
this.fetchConfigurationDetails();
|
this.fetchConfigurationDetails();
|
||||||
configureSentry(true);
|
|
||||||
|
tryInitializeSentry(ServerContext.config);
|
||||||
|
|
||||||
this.toggleNotificationDrawer = this.toggleNotificationDrawer.bind(this);
|
this.toggleNotificationDrawer = this.toggleNotificationDrawer.bind(this);
|
||||||
this.toggleApiDrawer = this.toggleApiDrawer.bind(this);
|
this.toggleApiDrawer = this.toggleApiDrawer.bind(this);
|
||||||
this.fetchConfigurationDetails = this.fetchConfigurationDetails.bind(this);
|
this.fetchConfigurationDetails = this.fetchConfigurationDetails.bind(this);
|
||||||
@ -325,6 +327,8 @@ export class UserInterface extends AuthenticatedInterface {
|
|||||||
this.me = session;
|
this.me = session;
|
||||||
this.uiConfig = getConfigForUser(session.user);
|
this.uiConfig = getConfigForUser(session.user);
|
||||||
|
|
||||||
|
setSentryPII(session.user);
|
||||||
|
|
||||||
new EventsApi(DEFAULT_CONFIG)
|
new EventsApi(DEFAULT_CONFIG)
|
||||||
.eventsNotificationsList({
|
.eventsNotificationsList({
|
||||||
seen: false,
|
seen: false,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { AndNext } from "@goauthentik/common/api/config";
|
import { AndNext } from "@goauthentik/common/api/config";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -32,7 +32,7 @@ export class UserSettingsPassword extends AKElement {
|
|||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<a
|
<a
|
||||||
href="${ifDefined(this.configureUrl)}${AndNext(
|
href="${ifDefined(this.configureUrl)}${AndNext(
|
||||||
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
|
`${ServerContext.baseURL}if/user/#/settings;${JSON.stringify({ page: "page-details" })}`,
|
||||||
)}"
|
)}"
|
||||||
class="pf-c-button pf-m-primary"
|
class="pf-c-button pf-m-primary"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import {
|
|||||||
parseAPIResponseError,
|
parseAPIResponseError,
|
||||||
pluckErrorDetail,
|
pluckErrorDetail,
|
||||||
} from "@goauthentik/common/errors/network";
|
} from "@goauthentik/common/errors/network";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { refreshMe } from "@goauthentik/common/users";
|
import { refreshMe } from "@goauthentik/common/users";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -173,14 +173,15 @@ export class UserSettingsFlowExecutor
|
|||||||
level: MessageLevel.success,
|
level: MessageLevel.success,
|
||||||
message: msg("Successfully updated details"),
|
message: msg("Successfully updated details"),
|
||||||
});
|
});
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true} header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`;
|
||||||
default:
|
default:
|
||||||
console.debug(
|
console.debug(
|
||||||
`authentik/user/flows: unsupported stage type ${this.challenge.component}`,
|
`authentik/user/flows: unsupported stage type ${this.challenge.component}`,
|
||||||
);
|
);
|
||||||
return html`
|
return html`
|
||||||
<a
|
<a
|
||||||
href="${globalAK().api.base}if/flow/${this.flowSlug}/"
|
href="${ServerContext.baseURL}if/flow/${this.flowSlug}/"
|
||||||
class="pf-c-button pf-m-primary"
|
class="pf-c-button pf-m-primary"
|
||||||
>
|
>
|
||||||
${msg("Open settings")}
|
${msg("Open settings")}
|
||||||
@ -194,7 +195,8 @@ export class UserSettingsFlowExecutor
|
|||||||
return html`<p>${msg("No settings flow configured.")}</p> `;
|
return html`<p>${msg("No settings flow configured.")}</p> `;
|
||||||
}
|
}
|
||||||
if (!this.challenge || this.loading) {
|
if (!this.challenge || this.loading) {
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading=${true} header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html` ${this.renderChallenge()} `;
|
return html` ${this.renderChallenge()} `;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
|||||||
${this.host.brand?.flowUnenrollment
|
${this.host.brand?.flowUnenrollment
|
||||||
? html` <a
|
? html` <a
|
||||||
class="pf-c-button pf-m-danger"
|
class="pf-c-button pf-m-danger"
|
||||||
href="${globalAK().api.base}if/flow/${this.host.brand
|
href="${ServerContext.baseURL}if/flow/${this.host.brand
|
||||||
.flowUnenrollment}/"
|
.flowUnenrollment}/"
|
||||||
>
|
>
|
||||||
${msg("Delete account")}
|
${msg("Delete account")}
|
||||||
@ -64,7 +64,8 @@ export class UserSettingsPromptStage extends PromptStage {
|
|||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
if (!this.challenge) {
|
if (!this.challenge) {
|
||||||
return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
|
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
|
||||||
|
</ak-empty-state>`;
|
||||||
}
|
}
|
||||||
return html`<div class="pf-c-login__main-body">
|
return html`<div class="pf-c-login__main-body">
|
||||||
<form
|
<form
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
import { deviceTypeName } from "@goauthentik/common/labels";
|
import { deviceTypeName } from "@goauthentik/common/labels";
|
||||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
||||||
|
import { ServerContext } from "@goauthentik/common/server-context";
|
||||||
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
import "@goauthentik/elements/buttons/ModalButton";
|
import "@goauthentik/elements/buttons/ModalButton";
|
||||||
@ -74,7 +74,7 @@ export class MFADevicesPage extends Table<Device> {
|
|||||||
return html`<li>
|
return html`<li>
|
||||||
<a
|
<a
|
||||||
href="${ifDefined(stage.configureUrl)}${AndNext(
|
href="${ifDefined(stage.configureUrl)}${AndNext(
|
||||||
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({
|
`${ServerContext.baseURL}if/user/#/settings;${JSON.stringify({
|
||||||
page: "page-mfa",
|
page: "page-mfa",
|
||||||
})}`,
|
})}`,
|
||||||
)}"
|
)}"
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Willkommen,
|
<target>Willkommen,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9171,9 +9171,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -493,7 +493,7 @@
|
|||||||
<target>General system status</target>
|
<target>General system status</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Welcome,
|
<target>Welcome,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -7694,9 +7694,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Bienvenido,
|
<target>Bienvenido,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9253,9 +9253,6 @@ Las vinculaciones a grupos o usuarios se comparan con el usuario del evento.</ta
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Bienvenue,
|
<target>Bienvenue,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9805,9 +9805,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
<target>Nombre d'anciens mots de passe à vérifier</target>
|
<target>Nombre d'anciens mots de passe à vérifier</target>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Benvenuto,
|
<target>Benvenuto,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9779,9 +9779,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -597,7 +597,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sc381422c585b867f">
|
<trans-unit id="sc381422c585b867f">
|
||||||
@ -9161,9 +9161,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -605,7 +605,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Welkom,
|
<target>Welkom,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9063,9 +9063,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Witaj,
|
<target>Witaj,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9488,9 +9488,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -603,7 +603,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Ŵēĺćōḿē, <x id="0" equiv-text="${name || ""}"/>.</target>
|
<target>Ŵēĺćōḿē, <x id="0" equiv-text="${name || ""}"/>.</target>
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -9496,7 +9496,4 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
|
||||||
</body></file></xliff>
|
</body></file></xliff>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Добро пожаловать,
|
<target>Добро пожаловать,
|
||||||
<x id="0" equiv-text="${name}"/>.</target>
|
<x id="0" equiv-text="${name}"/>.</target>
|
||||||
|
|
||||||
@ -9581,9 +9581,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -602,7 +602,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>Hoş geldiniz, <x id="0" equiv-text="${name || ""}"/>.</target>
|
<target>Hoş geldiniz, <x id="0" equiv-text="${name || ""}"/>.</target>
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -9551,9 +9551,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -399,7 +399,7 @@
|
|||||||
<source>General system status</source>
|
<source>General system status</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sc381422c585b867f">
|
<trans-unit id="sc381422c585b867f">
|
||||||
<source>Quick actions</source>
|
<source>Quick actions</source>
|
||||||
@ -6302,9 +6302,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>欢迎,
|
<target>欢迎,
|
||||||
<x id="0" equiv-text="${name}"/>。</target>
|
<x id="0" equiv-text="${name}"/>。</target>
|
||||||
|
|
||||||
@ -9806,10 +9806,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
<target>检查历史密码数量</target>
|
<target>检查历史密码数量</target>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
<target>切换侧边栏</target>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -485,7 +485,7 @@
|
|||||||
<target>常规系统状态</target>
|
<target>常规系统状态</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>欢迎,
|
<target>欢迎,
|
||||||
<x id="0" equiv-text="${name}"/>。</target>
|
<x id="0" equiv-text="${name}"/>。</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -7394,9 +7394,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -612,7 +612,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
<target>欢迎,
|
<target>欢迎,
|
||||||
<x id="0" equiv-text="${name}"/>。</target>
|
<x id="0" equiv-text="${name}"/>。</target>
|
||||||
|
|
||||||
@ -9806,10 +9806,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
<target>检查历史密码数量</target>
|
<target>检查历史密码数量</target>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
<target>切换侧边栏</target>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
@ -596,7 +596,7 @@
|
|||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s6dfd15978586d05f">
|
<trans-unit id="s6dfd15978586d05f">
|
||||||
<source>Welcome, <x id="0" equiv-text="${username || ""}"/>.</source>
|
<source>Welcome, <x id="0" equiv-text="${name || ""}"/>.</source>
|
||||||
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sc381422c585b867f">
|
<trans-unit id="sc381422c585b867f">
|
||||||
@ -9138,9 +9138,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="s79b3fcd40dd63921">
|
<trans-unit id="s79b3fcd40dd63921">
|
||||||
<source>Number of previous passwords to check</source>
|
<source>Number of previous passwords to check</source>
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="sdd66c5a2e706fb81">
|
|
||||||
<source>Toggle sidebar</source>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
2
website/.gitignore
vendored
2
website/.gitignore
vendored
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
# Production
|
# Production
|
||||||
/build
|
/build
|
||||||
/out
|
|
||||||
/help
|
/help
|
||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
@ -26,5 +25,4 @@ yarn-error.log*
|
|||||||
|
|
||||||
static/docker-compose.yml
|
static/docker-compose.yml
|
||||||
static/schema.yml
|
static/schema.yml
|
||||||
static/releases.gen.json
|
|
||||||
docs/developer-docs/api/reference/**
|
docs/developer-docs/api/reference/**
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
# Ignore artifacts:
|
# Ignore artifacts:
|
||||||
build
|
build
|
||||||
out
|
|
||||||
coverage
|
coverage
|
||||||
.docusaurus
|
.docusaurus
|
||||||
node_modules
|
node_modules
|
||||||
|
|||||||
1
website/.prettierrc.json
Normal file
1
website/.prettierrc.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Email Authenticator Setup stage
|
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.
|
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.
|
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,6 +2,8 @@
|
|||||||
title: WebAuthn / Passkeys Authenticator setup stage
|
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.
|
This stage configures a WebAuthn-based Authenticator. This can either be a browser, biometrics or a Security stick like a YubiKey.
|
||||||
|
|
||||||
### Options
|
### 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.
|
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 TabItem from "@theme/TabItem";
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
|
import TabItem from "@theme/TabItem";
|
||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultValue="docker-compose"
|
defaultValue="docker-compose"
|
||||||
|
|||||||
@ -2,9 +2,8 @@
|
|||||||
title: Caddy
|
title: Caddy
|
||||||
---
|
---
|
||||||
|
|
||||||
import TabItem from "@theme/TabItem";
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
|
import TabItem from "@theme/TabItem";
|
||||||
import Placeholders from "./__placeholders.md";
|
import Placeholders from "./__placeholders.md";
|
||||||
import CaddyStandalone from "./_caddy_standalone.md";
|
import CaddyStandalone from "./_caddy_standalone.md";
|
||||||
|
|
||||||
|
|||||||
@ -2,12 +2,13 @@
|
|||||||
title: Envoy
|
title: Envoy
|
||||||
---
|
---
|
||||||
|
|
||||||
import TabItem from "@theme/TabItem";
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
|
import TabItem from "@theme/TabItem";
|
||||||
import Placeholders from "./__placeholders.md";
|
import Placeholders from "./__placeholders.md";
|
||||||
import EnvoyIstio from "./_envoy_istio.md";
|
import EnvoyIstio from "./_envoy_istio.md";
|
||||||
|
|
||||||
|
# Envoy
|
||||||
|
|
||||||
The configuration template shown below apply to both single-application and domain-level forward auth.
|
The configuration template shown below apply to both single-application and domain-level forward auth.
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import TabItem from "@theme/TabItem";
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
|
import TabItem from "@theme/TabItem";
|
||||||
|
|
||||||
# nginx
|
# nginx
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import TabItem from "@theme/TabItem";
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
|
import TabItem from "@theme/TabItem";
|
||||||
|
|
||||||
# Traefik
|
# Traefik
|
||||||
|
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
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
|
title: RADIUS Provider
|
||||||
---
|
---
|
||||||
|
|
||||||
import { HashSupport } from "./HashSupport";
|
import { Check, X, AlertTriangle } from "react-feather";
|
||||||
|
|
||||||
You can configure a Radius provider for applications that don't support any other protocols or that require Radius.
|
You can configure a Radius provider for applications that don't support any other protocols or that require Radius.
|
||||||
|
|
||||||
@ -56,4 +56,15 @@ 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:
|
The RADIUS provider only supports the [PAP](https://en.wikipedia.org/wiki/Password_Authentication_Protocol) (Password Authentication Protocol) protocol:
|
||||||
|
|
||||||
<HashSupport />
|
| | 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> |
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
.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,7 +4,6 @@ title: Example
|
|||||||
|
|
||||||
This is one of the default packaged blueprints to create the default authentication flow.
|
This is one of the default packaged blueprints to create the default authentication flow.
|
||||||
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
```yaml
|
```yaml
|
||||||
version: 1
|
version: 1
|
||||||
metadata:
|
metadata:
|
||||||
@ -65,4 +64,3 @@ entries:
|
|||||||
target: !KeyOf flow
|
target: !KeyOf flow
|
||||||
model: authentik_flows.flowstagebinding
|
model: authentik_flows.flowstagebinding
|
||||||
```
|
```
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user