Compare commits
	
		
			120 Commits
		
	
	
		
			website/do
			...
			manualdeps
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| acc7ed2744 | |||
| b448e76db4 | |||
| f2937bd6dd | |||
| 53c2e3e77c | |||
| 7dd62c1f55 | |||
| 33e3510fba | |||
| 0e5fac2642 | |||
| c53b1fe78a | |||
| 838a7457b2 | |||
| a3c07bc9ff | |||
| 121f2c609d | |||
| 365affc28e | |||
| f367822779 | |||
| 848198125d | |||
| 497ac5e3d0 | |||
| 1773d4d681 | |||
| 4edbb51939 | |||
| c7e97ab48e | |||
| 31f7faae1c | |||
| f5dae2ae92 | |||
| 2c043dba0b | |||
| bda10e5db1 | |||
| be9ae7d4f7 | |||
| b4a6189bfa | |||
| bfdb827ff9 | |||
| 488a58e1c5 | |||
| 3f83e69453 | |||
| e92fa5df0b | |||
| f8c22170df | |||
| e3d08a8434 | |||
| 97d3e9afdc | |||
| 1eb08def73 | |||
| 6e3b379e4a | |||
| 264f59775c | |||
| d048f1ecbd | |||
| eb31f31584 | |||
| fe5c842e92 | |||
| b82d3100c9 | |||
| 49bb668036 | |||
| 52c70c7700 | |||
| b99fd36f86 | |||
| 8a5381eca3 | |||
| 2c77830179 | |||
| ffcd7def60 | |||
| ed121bc2a3 | |||
| d5ab9d9167 | |||
| a983321ad6 | |||
| 9c3420ede4 | |||
| 91b40350aa | |||
| 1912991682 | |||
| 71b9117f53 | |||
| b5f947f460 | |||
| 3a2f7e9549 | |||
| 1582ce0920 | |||
| 6d3eea5266 | |||
| e987208bd1 | |||
| 0efab8eef7 | |||
| 9402dac8ae | |||
| f57a290eee | |||
| 5dab0d2b7a | |||
| 2da6036248 | |||
| cdba94cea4 | |||
| c59eca664a | |||
| d5b205f9c0 | |||
| 8ad9ad833e | |||
| 599ce15f68 | |||
| 91310eff52 | |||
| b522d6732a | |||
| 17d96f204e | |||
| 65e4667bc3 | |||
| f67f9e5ed0 | |||
| 62dd6a4393 | |||
| a46eae8276 | |||
| c4acc9fc24 | |||
| e748a03082 | |||
| e473f28e21 | |||
| f70635c295 | |||
| 70d60c7ab2 | |||
| 61a26c02b7 | |||
| a06645d558 | |||
| 7730ecbd37 | |||
| 80e1be8db7 | |||
| c528c74e48 | |||
| 6d7bf36afe | |||
| 44fb59eb18 | |||
| 8f8d924935 | |||
| 602adaa5c5 | |||
| 5c9e97e11c | |||
| 2e7c620c9c | |||
| 30a2770781 | |||
| ef49fa0e79 | |||
| ac524ef425 | |||
| 6f3c1c4537 | |||
| 87886ca1b6 | |||
| 7ff96e30f9 | |||
| b26271557a | |||
| 15c99ff129 | |||
| 2a38e08e31 | |||
| 3696706466 | |||
| d0c9635033 | |||
| 7731014e1c | |||
| d478582a5c | |||
| 6255f380aa | |||
| 1f02e67c5c | |||
| d0bfb894b4 | |||
| c5dfdc6deb | |||
| d04a66ad9a | |||
| a5edaabec0 | |||
| daa367bc62 | |||
| 78345853c2 | |||
| f0fa8a3226 | |||
| 3335fdc6ad | |||
| 29c2c0f7dc | |||
| ada4254f52 | |||
| 39035de552 | |||
| e76d388ce4 | |||
| a52f887692 | |||
| d8b12a9a07 | |||
| ec01f16e99 | |||
| 9e3aaefc20 | 
@ -1,5 +1,5 @@
 | 
			
		||||
[bumpversion]
 | 
			
		||||
current_version = 2025.2.4
 | 
			
		||||
current_version = 2025.4.0
 | 
			
		||||
tag = True
 | 
			
		||||
commit = True
 | 
			
		||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							@ -118,3 +118,15 @@ updates:
 | 
			
		||||
      prefix: "core:"
 | 
			
		||||
    labels:
 | 
			
		||||
      - dependencies
 | 
			
		||||
  - package-ecosystem: docker-compose
 | 
			
		||||
    directories:
 | 
			
		||||
      # - /scripts # Maybe
 | 
			
		||||
      - /tests/e2e
 | 
			
		||||
    schedule:
 | 
			
		||||
      interval: daily
 | 
			
		||||
      time: "04:00"
 | 
			
		||||
    open-pull-requests-limit: 10
 | 
			
		||||
    commit-message:
 | 
			
		||||
      prefix: "core:"
 | 
			
		||||
    labels:
 | 
			
		||||
      - dependencies
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							@ -70,22 +70,18 @@ jobs:
 | 
			
		||||
      - name: checkout stable
 | 
			
		||||
        run: |
 | 
			
		||||
          # Copy current, latest config to local
 | 
			
		||||
          # Temporarly comment the .github backup while migrating to uv
 | 
			
		||||
          cp authentik/lib/default.yml local.env.yml
 | 
			
		||||
          # cp -R .github ..
 | 
			
		||||
          cp -R .github ..
 | 
			
		||||
          cp -R scripts ..
 | 
			
		||||
          git checkout $(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1)
 | 
			
		||||
          # rm -rf .github/ scripts/
 | 
			
		||||
          # mv ../.github ../scripts .
 | 
			
		||||
          rm -rf scripts/
 | 
			
		||||
          mv ../scripts .
 | 
			
		||||
          rm -rf .github/ scripts/
 | 
			
		||||
          mv ../.github ../scripts .
 | 
			
		||||
      - name: Setup authentik env (stable)
 | 
			
		||||
        uses: ./.github/actions/setup
 | 
			
		||||
        with:
 | 
			
		||||
          postgresql_version: ${{ matrix.psql }}
 | 
			
		||||
        continue-on-error: true
 | 
			
		||||
      - name: run migrations to stable
 | 
			
		||||
        run: poetry run python -m lifecycle.migrate
 | 
			
		||||
        run: uv run python -m lifecycle.migrate
 | 
			
		||||
      - name: checkout current code
 | 
			
		||||
        run: |
 | 
			
		||||
          set -x
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							@ -29,7 +29,7 @@ jobs:
 | 
			
		||||
      - name: Generate API
 | 
			
		||||
        run: make gen-client-go
 | 
			
		||||
      - name: golangci-lint
 | 
			
		||||
        uses: golangci/golangci-lint-action@v7
 | 
			
		||||
        uses: golangci/golangci-lint-action@v8
 | 
			
		||||
        with:
 | 
			
		||||
          version: latest
 | 
			
		||||
          args: --timeout 5000s --verbose
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -16,7 +16,7 @@
 | 
			
		||||
    ],
 | 
			
		||||
    "typescript.preferences.importModuleSpecifier": "non-relative",
 | 
			
		||||
    "typescript.preferences.importModuleSpecifierEnding": "index",
 | 
			
		||||
    "typescript.tsdk": "./web/node_modules/typescript/lib",
 | 
			
		||||
    "typescript.tsdk": "./node_modules/typescript/lib",
 | 
			
		||||
    "typescript.enablePromptUseWorkspaceTsdk": true,
 | 
			
		||||
    "yaml.schemas": {
 | 
			
		||||
        "./blueprints/schema.json": "blueprints/**/*.yaml"
 | 
			
		||||
@ -30,7 +30,5 @@
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "go.testFlags": ["-count=1"],
 | 
			
		||||
    "github-actions.workflows.pinned.workflows": [
 | 
			
		||||
        ".github/workflows/ci-main.yml"
 | 
			
		||||
    ]
 | 
			
		||||
    "github-actions.workflows.pinned.workflows": [".github/workflows/ci-main.yml"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -85,18 +85,17 @@ FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
 | 
			
		||||
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
 | 
			
		||||
ENV GEOIPUPDATE_VERBOSE="1"
 | 
			
		||||
ENV GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID"
 | 
			
		||||
ENV GEOIPUPDATE_LICENSE_KEY_FILE="/run/secrets/GEOIPUPDATE_LICENSE_KEY"
 | 
			
		||||
 | 
			
		||||
USER root
 | 
			
		||||
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
 | 
			
		||||
    --mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
 | 
			
		||||
    mkdir -p /usr/share/GeoIP && \
 | 
			
		||||
    /bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
 | 
			
		||||
    /bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
 | 
			
		||||
 | 
			
		||||
# Stage 5: Download uv
 | 
			
		||||
FROM ghcr.io/astral-sh/uv:0.6.17 AS uv
 | 
			
		||||
FROM ghcr.io/astral-sh/uv:0.7.3 AS uv
 | 
			
		||||
# Stage 6: Base python image
 | 
			
		||||
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
 | 
			
		||||
FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base
 | 
			
		||||
 | 
			
		||||
ENV VENV_PATH="/ak-root/.venv" \
 | 
			
		||||
    PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \
 | 
			
		||||
 | 
			
		||||
@ -42,4 +42,4 @@ See [SECURITY.md](SECURITY.md)
 | 
			
		||||
 | 
			
		||||
## 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 [CONTRIBUTING.md file](./CONTRIBUTING.md).
 | 
			
		||||
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).
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
from os import environ
 | 
			
		||||
 | 
			
		||||
__version__ = "2025.2.4"
 | 
			
		||||
__version__ = "2025.4.0"
 | 
			
		||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedCom
 | 
			
		||||
    return component
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):  # noqa: W0613
 | 
			
		||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):
 | 
			
		||||
    """Workaround to set a default response for endpoints.
 | 
			
		||||
    Workaround suggested at
 | 
			
		||||
    <https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
 | 
			
		||||
 | 
			
		||||
@ -164,9 +164,7 @@ class BlueprintEntry:
 | 
			
		||||
        """Get the blueprint model, with yaml tags resolved if present"""
 | 
			
		||||
        return str(self.tag_resolver(self.model, blueprint))
 | 
			
		||||
 | 
			
		||||
    def get_permissions(
 | 
			
		||||
        self, blueprint: "Blueprint"
 | 
			
		||||
    ) -> Generator[BlueprintEntryPermission, None, None]:
 | 
			
		||||
    def get_permissions(self, blueprint: "Blueprint") -> Generator[BlueprintEntryPermission]:
 | 
			
		||||
        """Get permissions of this entry, with all yaml tags resolved"""
 | 
			
		||||
        for perm in self.permissions:
 | 
			
		||||
            yield BlueprintEntryPermission(
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ def migrate_custom_css(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
 | 
			
		||||
    if not path.exists():
 | 
			
		||||
        return
 | 
			
		||||
    css = path.read_text()
 | 
			
		||||
    Brand.objects.using(db_alias).update(branding_custom_css=css)
 | 
			
		||||
    Brand.objects.using(db_alias).all().update(branding_custom_css=css)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ class LogEventSerializer(PassiveSerializer):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@contextmanager
 | 
			
		||||
def capture_logs(log_default_output=True) -> Generator[list[LogEvent], None, None]:
 | 
			
		||||
def capture_logs(log_default_output=True) -> Generator[list[LogEvent]]:
 | 
			
		||||
    """Capture log entries created"""
 | 
			
		||||
    logs = []
 | 
			
		||||
    cap = LogCapture()
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
        {% endblock %}
 | 
			
		||||
        <link rel="stylesheet" type="text/css" href="{% static 'dist/sfe/bootstrap.min.css' %}">
 | 
			
		||||
        <meta name="sentry-trace" content="{{ sentry_trace }}" />
 | 
			
		||||
        <link rel="prefetch" href="{{ flow_background_url }}" />
 | 
			
		||||
        {% include "base/header_js.html" %}
 | 
			
		||||
        <style>
 | 
			
		||||
          html,
 | 
			
		||||
@ -22,7 +23,7 @@
 | 
			
		||||
            height: 100%;
 | 
			
		||||
          }
 | 
			
		||||
          body {
 | 
			
		||||
            background-image: url("{{ flow.background_url }}");
 | 
			
		||||
            background-image: url("{{ flow_background_url }}");
 | 
			
		||||
            background-repeat: no-repeat;
 | 
			
		||||
            background-size: cover;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
 | 
			
		||||
{% block head_before %}
 | 
			
		||||
{{ block.super }}
 | 
			
		||||
<link rel="prefetch" href="{{ flow.background_url }}" />
 | 
			
		||||
<link rel="prefetch" href="{{ flow_background_url }}" />
 | 
			
		||||
{% if flow.compatibility_mode and not inspector %}
 | 
			
		||||
<script>ShadyDOM = { force: !navigator.webdriver };</script>
 | 
			
		||||
{% endif %}
 | 
			
		||||
@ -21,7 +21,7 @@ window.authentik.flow = {
 | 
			
		||||
<script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
 | 
			
		||||
<style>
 | 
			
		||||
:root {
 | 
			
		||||
    --ak-flow-background: url("{{ flow.background_url }}");
 | 
			
		||||
    --ak-flow-background: url("{{ flow_background_url }}");
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,9 @@ class FlowInterfaceView(InterfaceView):
 | 
			
		||||
    """Flow interface"""
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
 | 
			
		||||
        kwargs["flow"] = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
 | 
			
		||||
        flow = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
 | 
			
		||||
        kwargs["flow"] = flow
 | 
			
		||||
        kwargs["flow_background_url"] = flow.background_url(self.request)
 | 
			
		||||
        kwargs["inspector"] = "inspector" in self.request.GET
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ class PropertyMappingManager:
 | 
			
		||||
        request: HttpRequest | None,
 | 
			
		||||
        return_mapping: bool = False,
 | 
			
		||||
        **kwargs,
 | 
			
		||||
    ) -> Generator[tuple[dict, PropertyMapping], None]:
 | 
			
		||||
    ) -> Generator[tuple[dict, PropertyMapping]]:
 | 
			
		||||
        """Iterate over all mappings that were pre-compiled and
 | 
			
		||||
        execute all of them with the given context"""
 | 
			
		||||
        if not self.__has_compiled:
 | 
			
		||||
 | 
			
		||||
@ -199,7 +199,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
 | 
			
		||||
            chunk_size = len(ops)
 | 
			
		||||
        if len(ops) < 1:
 | 
			
		||||
            return
 | 
			
		||||
        for chunk in batched(ops, chunk_size):
 | 
			
		||||
        for chunk in batched(ops, chunk_size, strict=False):
 | 
			
		||||
            req = PatchRequest(Operations=list(chunk))
 | 
			
		||||
            self._request(
 | 
			
		||||
                "PATCH",
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -2,7 +2,7 @@
 | 
			
		||||
    "$schema": "http://json-schema.org/draft-07/schema",
 | 
			
		||||
    "$id": "https://goauthentik.io/blueprints/schema.json",
 | 
			
		||||
    "type": "object",
 | 
			
		||||
    "title": "authentik 2025.2.4 Blueprint schema",
 | 
			
		||||
    "title": "authentik 2025.4.0 Blueprint schema",
 | 
			
		||||
    "required": [
 | 
			
		||||
        "version",
 | 
			
		||||
        "entries"
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ services:
 | 
			
		||||
    volumes:
 | 
			
		||||
      - redis:/data
 | 
			
		||||
  server:
 | 
			
		||||
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.4}
 | 
			
		||||
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.0}
 | 
			
		||||
    restart: unless-stopped
 | 
			
		||||
    command: server
 | 
			
		||||
    environment:
 | 
			
		||||
@ -55,7 +55,7 @@ services:
 | 
			
		||||
      redis:
 | 
			
		||||
        condition: service_healthy
 | 
			
		||||
  worker:
 | 
			
		||||
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.4}
 | 
			
		||||
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.0}
 | 
			
		||||
    restart: unless-stopped
 | 
			
		||||
    command: worker
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							@ -19,18 +19,18 @@ require (
 | 
			
		||||
	github.com/jellydator/ttlcache/v3 v3.3.0
 | 
			
		||||
	github.com/mitchellh/mapstructure v1.5.0
 | 
			
		||||
	github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
 | 
			
		||||
	github.com/pires/go-proxyproto v0.8.0
 | 
			
		||||
	github.com/pires/go-proxyproto v0.8.1
 | 
			
		||||
	github.com/prometheus/client_golang v1.22.0
 | 
			
		||||
	github.com/redis/go-redis/v9 v9.7.3
 | 
			
		||||
	github.com/sethvargo/go-envconfig v1.2.0
 | 
			
		||||
	github.com/redis/go-redis/v9 v9.8.0
 | 
			
		||||
	github.com/sethvargo/go-envconfig v1.3.0
 | 
			
		||||
	github.com/sirupsen/logrus v1.9.3
 | 
			
		||||
	github.com/spf13/cobra v1.9.1
 | 
			
		||||
	github.com/stretchr/testify v1.10.0
 | 
			
		||||
	github.com/wwt/guac v1.3.2
 | 
			
		||||
	goauthentik.io/api/v3 v3.2025024.9
 | 
			
		||||
	goauthentik.io/api/v3 v3.2025040.1
 | 
			
		||||
	golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
 | 
			
		||||
	golang.org/x/oauth2 v0.29.0
 | 
			
		||||
	golang.org/x/sync v0.13.0
 | 
			
		||||
	golang.org/x/oauth2 v0.30.0
 | 
			
		||||
	golang.org/x/sync v0.14.0
 | 
			
		||||
	gopkg.in/yaml.v2 v2.4.0
 | 
			
		||||
	layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
 | 
			
		||||
)
 | 
			
		||||
@ -75,7 +75,7 @@ require (
 | 
			
		||||
	go.opentelemetry.io/otel/trace v1.24.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.36.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.31.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.23.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.24.0 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.36.5 // indirect
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								go.sum
									
									
									
									
									
								
							@ -230,8 +230,8 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+
 | 
			
		||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
 | 
			
		||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
 | 
			
		||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
 | 
			
		||||
github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0=
 | 
			
		||||
github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=
 | 
			
		||||
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
 | 
			
		||||
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
 | 
			
		||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
			
		||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
@ -245,14 +245,14 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
 | 
			
		||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
 | 
			
		||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 | 
			
		||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 | 
			
		||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
 | 
			
		||||
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
 | 
			
		||||
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
 | 
			
		||||
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
 | 
			
		||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
			
		||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
 | 
			
		||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 | 
			
		||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
			
		||||
github.com/sethvargo/go-envconfig v1.2.0 h1:q3XkOZWkC+G1sMLCrw9oPGTjYexygLOXDmGUit1ti8Q=
 | 
			
		||||
github.com/sethvargo/go-envconfig v1.2.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
 | 
			
		||||
github.com/sethvargo/go-envconfig v1.3.0 h1:gJs+Fuv8+f05omTpwWIu6KmuseFAXKrIaOZSh8RMt0U=
 | 
			
		||||
github.com/sethvargo/go-envconfig v1.3.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 | 
			
		||||
@ -290,8 +290,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
 | 
			
		||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
 | 
			
		||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 | 
			
		||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 | 
			
		||||
goauthentik.io/api/v3 v3.2025024.9 h1:i3tbkyotE32ZpJ729BsPWTuLQUdtZ54Li4aP1amZzsM=
 | 
			
		||||
goauthentik.io/api/v3 v3.2025024.9/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
 | 
			
		||||
goauthentik.io/api/v3 v3.2025040.1 h1:rQEcMNpz84/LPX8LVFteOJuserrd4PnU4k1Iu/wWqhs=
 | 
			
		||||
goauthentik.io/api/v3 v3.2025040.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
@ -358,16 +358,16 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
 | 
			
		||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 | 
			
		||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 | 
			
		||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 | 
			
		||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
 | 
			
		||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 | 
			
		||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
 | 
			
		||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
			
		||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
			
		||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
 | 
			
		||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
 | 
			
		||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
@ -376,8 +376,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
 | 
			
		||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
 | 
			
		||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 | 
			
		||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
 | 
			
		||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
@ -412,8 +412,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
			
		||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
 | 
			
		||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 | 
			
		||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
 | 
			
		||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
 | 
			
		||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
 | 
			
		||||
@ -29,4 +29,4 @@ func UserAgent() string {
 | 
			
		||||
	return fmt.Sprintf("authentik@%s", FullVersion())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const VERSION = "2025.2.4"
 | 
			
		||||
const VERSION = "2025.4.0"
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ EXPOSE 3389 6636 9300
 | 
			
		||||
 | 
			
		||||
USER 1000
 | 
			
		||||
 | 
			
		||||
ENV GOFIPS=1
 | 
			
		||||
ENV TMPDIR=/dev/shm/ \
 | 
			
		||||
    GOFIPS=1
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["/ldap"]
 | 
			
		||||
 | 
			
		||||
@ -97,6 +97,7 @@ elif [[ "$1" == "test-all" ]]; then
 | 
			
		||||
elif [[ "$1" == "healthcheck" ]]; then
 | 
			
		||||
    run_authentik healthcheck $(cat $MODE_FILE)
 | 
			
		||||
elif [[ "$1" == "dump_config" ]]; then
 | 
			
		||||
    shift
 | 
			
		||||
    exec python -m authentik.lib.config $@
 | 
			
		||||
elif [[ "$1" == "debug" ]]; then
 | 
			
		||||
    exec sleep infinity
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								lifecycle/aws/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								lifecycle/aws/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -9,7 +9,7 @@
 | 
			
		||||
            "version": "0.0.0",
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "devDependencies": {
 | 
			
		||||
                "aws-cdk": "^2.1012.0",
 | 
			
		||||
                "aws-cdk": "^2.1014.0",
 | 
			
		||||
                "cross-env": "^7.0.3"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
@ -17,9 +17,9 @@
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/aws-cdk": {
 | 
			
		||||
            "version": "2.1012.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1012.0.tgz",
 | 
			
		||||
            "integrity": "sha512-C6jSWkqP0hkY2Cs300VJHjspmTXDTMfB813kwZvRbd/OsKBfTBJBbYU16VoLAp1LVEOnQMf8otSlaSgzVF0X9A==",
 | 
			
		||||
            "version": "2.1014.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1014.0.tgz",
 | 
			
		||||
            "integrity": "sha512-es101rtRAClix9BncNL54iW90MiOyRv4iCC5tv/firGDnidS6pPinuK0IIFt0RO6w0+3heRxWBXg8HY+f9877w==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "Apache-2.0",
 | 
			
		||||
            "bin": {
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@
 | 
			
		||||
        "node": ">=20"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "aws-cdk": "^2.1012.0",
 | 
			
		||||
        "aws-cdk": "^2.1014.0",
 | 
			
		||||
        "cross-env": "^7.0.3"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ Parameters:
 | 
			
		||||
    Description: authentik Docker image
 | 
			
		||||
  AuthentikVersion:
 | 
			
		||||
    Type: String
 | 
			
		||||
    Default: 2025.2.4
 | 
			
		||||
    Default: 2025.4.0
 | 
			
		||||
    Description: authentik Docker image tag
 | 
			
		||||
  AuthentikServerCPU:
 | 
			
		||||
    Type: Number
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -12,8 +12,8 @@
 | 
			
		||||
# tmassimi, 2024
 | 
			
		||||
# Marc Schmitt, 2024
 | 
			
		||||
# albanobattistella <albanobattistella@gmail.com>, 2024
 | 
			
		||||
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
 | 
			
		||||
# Matteo Piccina <altermatte@gmail.com>, 2025
 | 
			
		||||
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
 | 
			
		||||
# 
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgid ""
 | 
			
		||||
@ -22,7 +22,7 @@ msgstr ""
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2025-04-23 09:00+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
 | 
			
		||||
"Last-Translator: Matteo Piccina <altermatte@gmail.com>, 2025\n"
 | 
			
		||||
"Last-Translator: Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025\n"
 | 
			
		||||
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
@ -383,7 +383,7 @@ msgstr "Mappatura delle proprietà"
 | 
			
		||||
 | 
			
		||||
#: authentik/core/models.py
 | 
			
		||||
msgid "session data"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "dati sessione"
 | 
			
		||||
 | 
			
		||||
#: authentik/core/models.py
 | 
			
		||||
msgid "Session"
 | 
			
		||||
@ -509,7 +509,7 @@ msgstr ""
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
msgid "Number of passwords to check against."
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Numero di password da verificare."
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
#: authentik/policies/password/models.py
 | 
			
		||||
@ -519,18 +519,19 @@ msgstr "Password non impostata nel contesto"
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
msgid "This password has been used previously. Please choose a different one."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Questa password è già stata utilizzata in precedenza. Scegline una diversa."
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
msgid "Password Uniqueness Policy"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Politica di unicità della password"
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
msgid "Password Uniqueness Policies"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Criteri di unicità delle password"
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policies/unique_password/models.py
 | 
			
		||||
msgid "User Password History"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Cronologia password utente"
 | 
			
		||||
 | 
			
		||||
#: authentik/enterprise/policy.py
 | 
			
		||||
msgid "Enterprise required to access this feature."
 | 
			
		||||
@ -2203,7 +2204,7 @@ msgstr "Ruoli"
 | 
			
		||||
 | 
			
		||||
#: authentik/rbac/models.py
 | 
			
		||||
msgid "Initial Permissions"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Permessi Iniziali"
 | 
			
		||||
 | 
			
		||||
#: authentik/rbac/models.py
 | 
			
		||||
msgid "System permission"
 | 
			
		||||
@ -2458,6 +2459,9 @@ msgid ""
 | 
			
		||||
"attribute. This allows nested group resolution on systems like FreeIPA and "
 | 
			
		||||
"Active Directory"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Cerca l'appartenenza al gruppo in base a un attributo utente anziché a un "
 | 
			
		||||
"attributo di gruppo. Questo consente la risoluzione di gruppi nidificati su "
 | 
			
		||||
"sistemi come FreeIPA e Active Directory."
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/models.py
 | 
			
		||||
msgid "LDAP Source"
 | 
			
		||||
@ -2477,19 +2481,19 @@ msgstr "Mappature delle proprietà della sorgente LDAP"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/models.py
 | 
			
		||||
msgid "User LDAP Source Connection"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Connessione Sorgente LDAP Utente"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/models.py
 | 
			
		||||
msgid "User LDAP Source Connections"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Connessioni Sorgente LDAP Utente"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/models.py
 | 
			
		||||
msgid "Group LDAP Source Connection"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Connessione Sorgente LDAP Gruppo"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/models.py
 | 
			
		||||
msgid "Group LDAP Source Connections"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Connessioni Sorgente LDAP Gruppo"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/ldap/signals.py
 | 
			
		||||
msgid "Password does not match Active Directory Complexity."
 | 
			
		||||
@ -2501,11 +2505,11 @@ msgstr "Nessun token ricevuto."
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/oauth/models.py
 | 
			
		||||
msgid "HTTP Basic Authentication"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "HTTP Basic Authentication"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/oauth/models.py
 | 
			
		||||
msgid "Include the client ID and secret as request parameters"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Includi il client ID e il segreto come parametri di richiesta"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/oauth/models.py
 | 
			
		||||
msgid "Request Token URL"
 | 
			
		||||
@ -2552,6 +2556,8 @@ msgid ""
 | 
			
		||||
"How to perform authentication during an authorization_code token request "
 | 
			
		||||
"flow"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Come eseguire l'autenticazione durante un flusso di richiesta del token "
 | 
			
		||||
"authorization_code"
 | 
			
		||||
 | 
			
		||||
#: authentik/sources/oauth/models.py
 | 
			
		||||
msgid "OAuth Source"
 | 
			
		||||
@ -3484,6 +3490,9 @@ msgid ""
 | 
			
		||||
"Show the user the 'Remember me on this device' toggle, allowing repeat users"
 | 
			
		||||
" to skip straight to entering their password."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Mostra all'utente il pulsante \"Ricordami su questo dispositivo\", "
 | 
			
		||||
"consentendo agli utenti abituali di passare direttamente all'inserimento "
 | 
			
		||||
"della password."
 | 
			
		||||
 | 
			
		||||
#: authentik/stages/identification/models.py
 | 
			
		||||
msgid "Optional enrollment flow, which is linked at the bottom of the page."
 | 
			
		||||
@ -3873,11 +3882,11 @@ msgstr ""
 | 
			
		||||
 | 
			
		||||
#: authentik/tenants/models.py
 | 
			
		||||
msgid "Reputation cannot decrease lower than this value. Zero or negative."
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "La reputazione non può scendere sotto questo valore. Zero o negativo."
 | 
			
		||||
 | 
			
		||||
#: authentik/tenants/models.py
 | 
			
		||||
msgid "Reputation cannot increase higher than this value. Zero or positive."
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "La reputazione non può superare questo valore. Zero o positivo."
 | 
			
		||||
 | 
			
		||||
#: authentik/tenants/models.py
 | 
			
		||||
msgid "The option configures the footer links on the flow executor pages."
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								locale/pt/LC_MESSAGES/django.mo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								locale/pt/LC_MESSAGES/django.mo
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3924
									
								
								locale/pt/LC_MESSAGES/django.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3924
									
								
								locale/pt/LC_MESSAGES/django.po
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										538
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										538
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1,12 +1,546 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/authentik",
 | 
			
		||||
    "version": "2025.2.1",
 | 
			
		||||
    "version": "2025.4.0",
 | 
			
		||||
    "lockfileVersion": 3,
 | 
			
		||||
    "requires": true,
 | 
			
		||||
    "packages": {
 | 
			
		||||
        "": {
 | 
			
		||||
            "name": "@goauthentik/authentik",
 | 
			
		||||
            "version": "2025.2.1"
 | 
			
		||||
            "version": "2025.4.0",
 | 
			
		||||
            "devDependencies": {
 | 
			
		||||
                "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
                "prettier": "^3.3.3",
 | 
			
		||||
                "prettier-plugin-organize-imports": "^4.1.0",
 | 
			
		||||
                "prettier-plugin-packagejson": "^2.5.10",
 | 
			
		||||
                "typescript": "^5.6.2"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/code-frame": {
 | 
			
		||||
            "version": "7.26.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
 | 
			
		||||
            "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/helper-validator-identifier": "^7.25.9",
 | 
			
		||||
                "js-tokens": "^4.0.0",
 | 
			
		||||
                "picocolors": "^1.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/generator": {
 | 
			
		||||
            "version": "7.27.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
 | 
			
		||||
            "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/parser": "^7.27.0",
 | 
			
		||||
                "@babel/types": "^7.27.0",
 | 
			
		||||
                "@jridgewell/gen-mapping": "^0.3.5",
 | 
			
		||||
                "@jridgewell/trace-mapping": "^0.3.25",
 | 
			
		||||
                "jsesc": "^3.0.2"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/helper-string-parser": {
 | 
			
		||||
            "version": "7.25.9",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
 | 
			
		||||
            "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/helper-validator-identifier": {
 | 
			
		||||
            "version": "7.25.9",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
 | 
			
		||||
            "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/parser": {
 | 
			
		||||
            "version": "7.27.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
 | 
			
		||||
            "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/types": "^7.27.0"
 | 
			
		||||
            },
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "parser": "bin/babel-parser.js"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.0.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/template": {
 | 
			
		||||
            "version": "7.27.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
 | 
			
		||||
            "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/code-frame": "^7.26.2",
 | 
			
		||||
                "@babel/parser": "^7.27.0",
 | 
			
		||||
                "@babel/types": "^7.27.0"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/traverse": {
 | 
			
		||||
            "version": "7.27.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
 | 
			
		||||
            "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/code-frame": "^7.26.2",
 | 
			
		||||
                "@babel/generator": "^7.27.0",
 | 
			
		||||
                "@babel/parser": "^7.27.0",
 | 
			
		||||
                "@babel/template": "^7.27.0",
 | 
			
		||||
                "@babel/types": "^7.27.0",
 | 
			
		||||
                "debug": "^4.3.1",
 | 
			
		||||
                "globals": "^11.1.0"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@babel/types": {
 | 
			
		||||
            "version": "7.27.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
 | 
			
		||||
            "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/helper-string-parser": "^7.25.9",
 | 
			
		||||
                "@babel/helper-validator-identifier": "^7.25.9"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.9.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@jridgewell/gen-mapping": {
 | 
			
		||||
            "version": "0.3.8",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
 | 
			
		||||
            "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@jridgewell/set-array": "^1.2.1",
 | 
			
		||||
                "@jridgewell/sourcemap-codec": "^1.4.10",
 | 
			
		||||
                "@jridgewell/trace-mapping": "^0.3.24"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.0.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@jridgewell/resolve-uri": {
 | 
			
		||||
            "version": "3.1.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
 | 
			
		||||
            "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.0.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@jridgewell/set-array": {
 | 
			
		||||
            "version": "1.2.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
 | 
			
		||||
            "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.0.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@jridgewell/sourcemap-codec": {
 | 
			
		||||
            "version": "1.5.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
 | 
			
		||||
            "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@jridgewell/trace-mapping": {
 | 
			
		||||
            "version": "0.3.25",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
 | 
			
		||||
            "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@jridgewell/resolve-uri": "^3.1.0",
 | 
			
		||||
                "@jridgewell/sourcemap-codec": "^1.4.14"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@pkgr/core": {
 | 
			
		||||
            "version": "0.1.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz",
 | 
			
		||||
            "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://opencollective.com/unts"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@trivago/prettier-plugin-sort-imports": {
 | 
			
		||||
            "version": "5.2.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-5.2.2.tgz",
 | 
			
		||||
            "integrity": "sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "Apache-2.0",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@babel/generator": "^7.26.5",
 | 
			
		||||
                "@babel/parser": "^7.26.7",
 | 
			
		||||
                "@babel/traverse": "^7.26.7",
 | 
			
		||||
                "@babel/types": "^7.26.7",
 | 
			
		||||
                "javascript-natural-sort": "^0.7.1",
 | 
			
		||||
                "lodash": "^4.17.21"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">18.12"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependencies": {
 | 
			
		||||
                "@vue/compiler-sfc": "3.x",
 | 
			
		||||
                "prettier": "2.x - 3.x",
 | 
			
		||||
                "prettier-plugin-svelte": "3.x",
 | 
			
		||||
                "svelte": "4.x || 5.x"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependenciesMeta": {
 | 
			
		||||
                "@vue/compiler-sfc": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                },
 | 
			
		||||
                "prettier-plugin-svelte": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                },
 | 
			
		||||
                "svelte": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/debug": {
 | 
			
		||||
            "version": "4.4.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
 | 
			
		||||
            "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "ms": "^2.1.3"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6.0"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependenciesMeta": {
 | 
			
		||||
                "supports-color": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/detect-indent": {
 | 
			
		||||
            "version": "7.0.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz",
 | 
			
		||||
            "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=12.20"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/detect-newline": {
 | 
			
		||||
            "version": "4.0.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz",
 | 
			
		||||
            "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/sponsors/sindresorhus"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/fdir": {
 | 
			
		||||
            "version": "6.4.4",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
 | 
			
		||||
            "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "peerDependencies": {
 | 
			
		||||
                "picomatch": "^3 || ^4"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependenciesMeta": {
 | 
			
		||||
                "picomatch": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/get-stdin": {
 | 
			
		||||
            "version": "9.0.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
 | 
			
		||||
            "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=12"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/sponsors/sindresorhus"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/git-hooks-list": {
 | 
			
		||||
            "version": "3.2.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-3.2.0.tgz",
 | 
			
		||||
            "integrity": "sha512-ZHG9a1gEhUMX1TvGrLdyWb9kDopCBbTnI8z4JgRMYxsijWipgjSEYoPWqBuIB0DnRnvqlQSEeVmzpeuPm7NdFQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/fisker/git-hooks-list?sponsor=1"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/globals": {
 | 
			
		||||
            "version": "11.12.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
 | 
			
		||||
            "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=4"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/is-plain-obj": {
 | 
			
		||||
            "version": "4.1.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
 | 
			
		||||
            "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=12"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/sponsors/sindresorhus"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/javascript-natural-sort": {
 | 
			
		||||
            "version": "0.7.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
 | 
			
		||||
            "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/js-tokens": {
 | 
			
		||||
            "version": "4.0.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
 | 
			
		||||
            "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/jsesc": {
 | 
			
		||||
            "version": "3.1.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
 | 
			
		||||
            "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "jsesc": "bin/jsesc"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=6"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/lodash": {
 | 
			
		||||
            "version": "4.17.21",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
 | 
			
		||||
            "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/ms": {
 | 
			
		||||
            "version": "2.1.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
 | 
			
		||||
            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/picocolors": {
 | 
			
		||||
            "version": "1.1.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
 | 
			
		||||
            "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "ISC"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/picomatch": {
 | 
			
		||||
            "version": "4.0.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
 | 
			
		||||
            "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=12"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/sponsors/jonschlinkert"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/prettier": {
 | 
			
		||||
            "version": "3.5.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
 | 
			
		||||
            "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "prettier": "bin/prettier.cjs"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=14"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/prettier/prettier?sponsor=1"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/prettier-plugin-organize-imports": {
 | 
			
		||||
            "version": "4.1.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz",
 | 
			
		||||
            "integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "peerDependencies": {
 | 
			
		||||
                "prettier": ">=2.0",
 | 
			
		||||
                "typescript": ">=2.9",
 | 
			
		||||
                "vue-tsc": "^2.1.0"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependenciesMeta": {
 | 
			
		||||
                "vue-tsc": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/prettier-plugin-packagejson": {
 | 
			
		||||
            "version": "2.5.10",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.10.tgz",
 | 
			
		||||
            "integrity": "sha512-LUxATI5YsImIVSaaLJlJ3aE6wTD+nvots18U3GuQMJpUyClChaZlQrqx3dBnbhF20OnKWZyx8EgyZypQtBDtgQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "sort-package-json": "2.15.1",
 | 
			
		||||
                "synckit": "0.9.2"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependencies": {
 | 
			
		||||
                "prettier": ">= 1.16.0"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependenciesMeta": {
 | 
			
		||||
                "prettier": {
 | 
			
		||||
                    "optional": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/semver": {
 | 
			
		||||
            "version": "7.7.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
 | 
			
		||||
            "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "ISC",
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "semver": "bin/semver.js"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=10"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/sort-object-keys": {
 | 
			
		||||
            "version": "1.1.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz",
 | 
			
		||||
            "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/sort-package-json": {
 | 
			
		||||
            "version": "2.15.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-2.15.1.tgz",
 | 
			
		||||
            "integrity": "sha512-9x9+o8krTT2saA9liI4BljNjwAbvUnWf11Wq+i/iZt8nl2UGYnf3TH5uBydE7VALmP7AGwlfszuEeL8BDyb0YA==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "detect-indent": "^7.0.1",
 | 
			
		||||
                "detect-newline": "^4.0.0",
 | 
			
		||||
                "get-stdin": "^9.0.0",
 | 
			
		||||
                "git-hooks-list": "^3.0.0",
 | 
			
		||||
                "is-plain-obj": "^4.1.0",
 | 
			
		||||
                "semver": "^7.6.0",
 | 
			
		||||
                "sort-object-keys": "^1.1.3",
 | 
			
		||||
                "tinyglobby": "^0.2.9"
 | 
			
		||||
            },
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "sort-package-json": "cli.js"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/synckit": {
 | 
			
		||||
            "version": "0.9.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
 | 
			
		||||
            "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@pkgr/core": "^0.1.0",
 | 
			
		||||
                "tslib": "^2.6.2"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": "^14.18.0 || >=16.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://opencollective.com/unts"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/tinyglobby": {
 | 
			
		||||
            "version": "0.2.13",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
 | 
			
		||||
            "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "fdir": "^6.4.4",
 | 
			
		||||
                "picomatch": "^4.0.2"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=12.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": {
 | 
			
		||||
                "url": "https://github.com/sponsors/SuperchupuDev"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/tslib": {
 | 
			
		||||
            "version": "2.8.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
 | 
			
		||||
            "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "0BSD"
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/typescript": {
 | 
			
		||||
            "version": "5.8.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
 | 
			
		||||
            "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "license": "Apache-2.0",
 | 
			
		||||
            "bin": {
 | 
			
		||||
                "tsc": "bin/tsc",
 | 
			
		||||
                "tsserver": "bin/tsserver"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=14.17"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								package.json
									
									
									
									
									
								
							@ -1,5 +1,15 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/authentik",
 | 
			
		||||
    "version": "2025.2.4",
 | 
			
		||||
    "private": true
 | 
			
		||||
    "version": "2025.4.0",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "prettier-plugin-organize-imports": "^4.1.0",
 | 
			
		||||
        "prettier-plugin-packagejson": "^2.5.10",
 | 
			
		||||
        "typescript": "^5.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "workspaces": [],
 | 
			
		||||
    "prettier": "./packages/prettier-config/index.js"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/docusaurus-config/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								packages/docusaurus-config/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/docusaurus-config",
 | 
			
		||||
    "version": "1.0.5",
 | 
			
		||||
    "version": "1.0.6",
 | 
			
		||||
    "lockfileVersion": 3,
 | 
			
		||||
    "requires": true,
 | 
			
		||||
    "packages": {
 | 
			
		||||
        "": {
 | 
			
		||||
            "name": "@goauthentik/docusaurus-config",
 | 
			
		||||
            "version": "1.0.5",
 | 
			
		||||
            "version": "1.0.6",
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "deepmerge-ts": "^7.1.5",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/docusaurus-config",
 | 
			
		||||
    "version": "1.0.5",
 | 
			
		||||
    "version": "1.0.6",
 | 
			
		||||
    "description": "authentik's Docusaurus config",
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "scripts": {
 | 
			
		||||
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/monorepo",
 | 
			
		||||
    "version": "1.0.0",
 | 
			
		||||
    "description": "Utilities for the authentik monorepo.",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "exports": {
 | 
			
		||||
        "./package.json": "./package.json",
 | 
			
		||||
        ".": {
 | 
			
		||||
            "import": "./index.js",
 | 
			
		||||
            "types": "./out/index.d.ts"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "types": "./out/index.d.ts",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
import { createRequire } from "node:module";
 | 
			
		||||
import { dirname, join, resolve } from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
 | 
			
		||||
const __dirname = dirname(fileURLToPath(import.meta.url));
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {'~authentik'} MonoRepoRoot
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The root of the authentik monorepo.
 | 
			
		||||
 */
 | 
			
		||||
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (resolve(__dirname, "..", ".."));
 | 
			
		||||
 | 
			
		||||
const require = createRequire(import.meta.url);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resolve a package name to its location in the monorepo to the single node_modules directory.
 | 
			
		||||
 * @param {string} packageName
 | 
			
		||||
 * @returns {string} The resolved path to the package.
 | 
			
		||||
 * @throws {Error} If the package cannot be resolved.
 | 
			
		||||
 */
 | 
			
		||||
export function resolvePackage(packageName) {
 | 
			
		||||
    const packageJSONPath = require.resolve(join(packageName, "package.json"), {
 | 
			
		||||
        paths: [MonoRepoRoot],
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return dirname(packageJSONPath);
 | 
			
		||||
}
 | 
			
		||||
@ -76,6 +76,7 @@ EXPOSE 9000 9300 9443
 | 
			
		||||
 | 
			
		||||
USER 1000
 | 
			
		||||
 | 
			
		||||
ENV GOFIPS=1
 | 
			
		||||
ENV TMPDIR=/dev/shm/ \
 | 
			
		||||
    GOFIPS=1
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["/proxy"]
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
[project]
 | 
			
		||||
name = "authentik"
 | 
			
		||||
version = "2025.2.4"
 | 
			
		||||
version = "2025.4.0"
 | 
			
		||||
description = ""
 | 
			
		||||
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
 | 
			
		||||
requires-python = "==3.12.*"
 | 
			
		||||
requires-python = "==3.13.*"
 | 
			
		||||
dependencies = [
 | 
			
		||||
    "argon2-cffi",
 | 
			
		||||
    "celery",
 | 
			
		||||
@ -52,7 +52,7 @@ dependencies = [
 | 
			
		||||
    "pydantic-scim",
 | 
			
		||||
    "pyjwt",
 | 
			
		||||
    "pyrad",
 | 
			
		||||
    "python-kadmin-rs ==0.6.0",
 | 
			
		||||
    "python-kadmin-rs",
 | 
			
		||||
    "pyyaml",
 | 
			
		||||
    "requests-oauthlib",
 | 
			
		||||
    "scim2-filter-parser",
 | 
			
		||||
@ -70,7 +70,7 @@ dependencies = [
 | 
			
		||||
    "watchdog",
 | 
			
		||||
    "webauthn",
 | 
			
		||||
    "wsproto",
 | 
			
		||||
    "xmlsec <= 1.3.14",
 | 
			
		||||
    "xmlsec",
 | 
			
		||||
    "zxcvbn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -101,6 +101,18 @@ dev = [
 | 
			
		||||
    "selenium",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[tool.uv]
 | 
			
		||||
no-binary-package = [
 | 
			
		||||
    # This differs from the no-binary packages in the Dockerfile. This is due to the fact
 | 
			
		||||
    # that these packages are built from source for different reasons than cryptography and kadmin.
 | 
			
		||||
    # These packages are built from source to link against the libxml2 on the system which is
 | 
			
		||||
    # required for functionality and to stay up-to-date on both libraries.
 | 
			
		||||
    # The other packages specified in the dockerfile are compiled from source to link against the
 | 
			
		||||
    # correct FIPS OpenSSL libraries
 | 
			
		||||
    "lxml",
 | 
			
		||||
    "xmlsec",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[tool.uv.sources]
 | 
			
		||||
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch = "authentik-fixes" }
 | 
			
		||||
opencontainers = { git = "https://github.com/BeryJu/oci-python", rev = "c791b19056769cd67957322806809ab70f5bead8" }
 | 
			
		||||
@ -143,12 +155,12 @@ ignore-words = ".github/codespell-words.txt"
 | 
			
		||||
 | 
			
		||||
[tool.black]
 | 
			
		||||
line-length = 100
 | 
			
		||||
target-version = ['py312']
 | 
			
		||||
target-version = ['py313']
 | 
			
		||||
exclude = 'node_modules'
 | 
			
		||||
 | 
			
		||||
[tool.ruff]
 | 
			
		||||
line-length = 100
 | 
			
		||||
target-version = "py312"
 | 
			
		||||
target-version = "py313"
 | 
			
		||||
exclude = ["**/migrations/**", "**/node_modules/**"]
 | 
			
		||||
 | 
			
		||||
[tool.ruff.lint]
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/rac", "healthch
 | 
			
		||||
 | 
			
		||||
USER 1000
 | 
			
		||||
 | 
			
		||||
ENV GOFIPS=1
 | 
			
		||||
ENV TMPDIR=/dev/shm/ \
 | 
			
		||||
    GOFIPS=1
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["/rac"]
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ EXPOSE 1812/udp 9300
 | 
			
		||||
 | 
			
		||||
USER 1000
 | 
			
		||||
 | 
			
		||||
ENV GOFIPS=1
 | 
			
		||||
ENV TMPDIR=/dev/shm/ \
 | 
			
		||||
    GOFIPS=1
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["/radius"]
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
openapi: 3.0.3
 | 
			
		||||
info:
 | 
			
		||||
  title: authentik
 | 
			
		||||
  version: 2025.2.4
 | 
			
		||||
  version: 2025.4.0
 | 
			
		||||
  description: Making authentication simple.
 | 
			
		||||
  contact:
 | 
			
		||||
    email: hello@goauthentik.io
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
services:
 | 
			
		||||
  chrome:
 | 
			
		||||
    image: docker.io/selenium/standalone-chrome:122.0
 | 
			
		||||
    image: docker.io/selenium/standalone-chrome:136.0
 | 
			
		||||
    volumes:
 | 
			
		||||
      - /dev/shm:/dev/shm
 | 
			
		||||
    network_mode: host
 | 
			
		||||
    restart: always
 | 
			
		||||
  mailpit:
 | 
			
		||||
    image: docker.io/axllent/mailpit:v1.6.5
 | 
			
		||||
    image: docker.io/axllent/mailpit:v1.24.2
 | 
			
		||||
    ports:
 | 
			
		||||
      - 1025:1025
 | 
			
		||||
      - 8025:8025
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ from selenium import webdriver
 | 
			
		||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException, WebDriverException
 | 
			
		||||
from selenium.webdriver.common.by import By
 | 
			
		||||
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.webelement import WebElement
 | 
			
		||||
from selenium.webdriver.support.wait import WebDriverWait
 | 
			
		||||
@ -197,7 +198,12 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
 | 
			
		||||
        super().tearDown()
 | 
			
		||||
        if IS_CI:
 | 
			
		||||
            print("::group::Browser logs")
 | 
			
		||||
        for line in self.driver.get_log("browser"):
 | 
			
		||||
        # Very verbose way to get browser logs
 | 
			
		||||
        # 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"])
 | 
			
		||||
        if IS_CI:
 | 
			
		||||
            print("::endgroup::")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
// TypeScript Project Configuration
 | 
			
		||||
{
 | 
			
		||||
    "extends": "./packages/tsconfig/tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "."
 | 
			
		||||
    },
 | 
			
		||||
    "watchOptions": {
 | 
			
		||||
        "excludeDirectories": [
 | 
			
		||||
            "**/.git", // Git
 | 
			
		||||
            "**/.yarn", // Yarn
 | 
			
		||||
            "**/.vscode", // VS Code
 | 
			
		||||
            "**/.vscode-test-web", // VS Code Web Test
 | 
			
		||||
            "**/dist", // Distributed build files
 | 
			
		||||
            "**/out", // Output build files
 | 
			
		||||
            "**/.drafts", // Drafts
 | 
			
		||||
            "**/.github", // GitHub
 | 
			
		||||
            "**/node_modules" // Node modules
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // The root project has no sources of its own. By setting `files` to an empty
 | 
			
		||||
    // list, TS won't automatically include all sources below root (the default).
 | 
			
		||||
    "files": [],
 | 
			
		||||
    "references": [
 | 
			
		||||
        // Note that references are in the order we want them to be built.
 | 
			
		||||
        // TODO: Left blank until TypeScript workspaces are complete.
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@ -2,15 +2,11 @@
 | 
			
		||||
node_modules
 | 
			
		||||
# don't lint build output (make sure it's set to your correct build folder name)
 | 
			
		||||
dist
 | 
			
		||||
out
 | 
			
		||||
# don't lint nyc coverage output
 | 
			
		||||
coverage
 | 
			
		||||
# Import order matters
 | 
			
		||||
poly.ts
 | 
			
		||||
src/locale-codes.ts
 | 
			
		||||
src/locales/
 | 
			
		||||
storybook-static/
 | 
			
		||||
# Prettier breaks the tsconfig file
 | 
			
		||||
tsconfig.json
 | 
			
		||||
.storybook/css-import-maps*
 | 
			
		||||
package.json
 | 
			
		||||
packages/**/package.json
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										855
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										855
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										115
									
								
								web/package.json
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								web/package.json
									
									
									
									
									
								
							@ -1,6 +1,44 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/web",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "wireit",
 | 
			
		||||
        "build-locales": "wireit",
 | 
			
		||||
        "build-locales:build": "wireit",
 | 
			
		||||
        "build-proxy": "wireit",
 | 
			
		||||
        "build:sfe": "wireit",
 | 
			
		||||
        "esbuild:watch": "node scripts/build-web.mjs --watch",
 | 
			
		||||
        "extract-locales": "wireit",
 | 
			
		||||
        "format": "wireit",
 | 
			
		||||
        "lint": "wireit",
 | 
			
		||||
        "lint:imports": "wireit",
 | 
			
		||||
        "lint:lockfile": "wireit",
 | 
			
		||||
        "lint:nightmare": "wireit",
 | 
			
		||||
        "lint:precommit": "wireit",
 | 
			
		||||
        "lint:types": "wireit",
 | 
			
		||||
        "lit-analyse": "wireit",
 | 
			
		||||
        "postinstall": "bash scripts/patch-spotlight.sh",
 | 
			
		||||
        "precommit": "wireit",
 | 
			
		||||
        "prettier": "wireit",
 | 
			
		||||
        "prettier-check": "wireit",
 | 
			
		||||
        "pseudolocalize": "wireit",
 | 
			
		||||
        "storybook": "storybook dev -p 6006",
 | 
			
		||||
        "storybook:build": "wireit",
 | 
			
		||||
        "test": "wireit",
 | 
			
		||||
        "test:e2e": "wireit",
 | 
			
		||||
        "test:e2e:watch": "wireit",
 | 
			
		||||
        "test:watch": "wireit",
 | 
			
		||||
        "tsc": "wireit",
 | 
			
		||||
        "watch": "run-s build-locales esbuild:watch"
 | 
			
		||||
    },
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "exports": {
 | 
			
		||||
        "./package.json": "./package.json",
 | 
			
		||||
        "./paths": "./paths.js",
 | 
			
		||||
        "./scripts/*": "./scripts/*.mjs"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@codemirror/lang-css": "^6.3.1",
 | 
			
		||||
        "@codemirror/lang-html": "^6.4.9",
 | 
			
		||||
@ -12,8 +50,7 @@
 | 
			
		||||
        "@floating-ui/dom": "^1.6.11",
 | 
			
		||||
        "@formatjs/intl-listformat": "^7.5.7",
 | 
			
		||||
        "@fortawesome/fontawesome-free": "^6.6.0",
 | 
			
		||||
        "@goauthentik/api": "^2025.2.4-1745519715",
 | 
			
		||||
        "@lit-labs/ssr": "3.2.2",
 | 
			
		||||
        "@goauthentik/api": "^2025.4.0-1746018955",
 | 
			
		||||
        "@lit/context": "^1.1.2",
 | 
			
		||||
        "@lit/localize": "^0.12.2",
 | 
			
		||||
        "@lit/reactive-element": "^2.0.4",
 | 
			
		||||
@ -54,6 +91,7 @@
 | 
			
		||||
        "remark-gfm": "^4.0.1",
 | 
			
		||||
        "remark-mdx-frontmatter": "^5.0.0",
 | 
			
		||||
        "style-mod": "^4.1.2",
 | 
			
		||||
        "trusted-types": "^2.0.0",
 | 
			
		||||
        "ts-pattern": "^5.4.0",
 | 
			
		||||
        "unist-util-visit": "^5.0.0",
 | 
			
		||||
        "webcomponent-qr-code": "^1.2.0",
 | 
			
		||||
@ -62,6 +100,7 @@
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@eslint/js": "^9.11.1",
 | 
			
		||||
        "@goauthentik/esbuild-plugin-live-reload": "^1.0.4",
 | 
			
		||||
        "@goauthentik/monorepo": "^1.0.0",
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@hcaptcha/types": "^1.0.4",
 | 
			
		||||
@ -93,13 +132,13 @@
 | 
			
		||||
        "@wdio/spec-reporter": "^9.1.2",
 | 
			
		||||
        "chromedriver": "^131.0.1",
 | 
			
		||||
        "esbuild": "^0.25.0",
 | 
			
		||||
        "esbuild-plugin-copy": "^2.1.1",
 | 
			
		||||
        "esbuild-plugin-polyfill-node": "^0.3.0",
 | 
			
		||||
        "esbuild-plugins-node-modules-polyfill": "^1.7.0",
 | 
			
		||||
        "eslint": "^9.11.1",
 | 
			
		||||
        "eslint-plugin-lit": "^1.15.0",
 | 
			
		||||
        "eslint-plugin-wc": "^2.1.1",
 | 
			
		||||
        "github-slugger": "^2.0.0",
 | 
			
		||||
        "glob": "^11.0.0",
 | 
			
		||||
        "globals": "^15.10.0",
 | 
			
		||||
        "knip": "^5.30.6",
 | 
			
		||||
        "lit-analyzer": "^2.0.3",
 | 
			
		||||
@ -110,7 +149,6 @@
 | 
			
		||||
        "rollup-plugin-postcss-lit": "^2.1.0",
 | 
			
		||||
        "storybook": "^8.3.4",
 | 
			
		||||
        "storybook-addon-mock": "^5.0.0",
 | 
			
		||||
        "syncpack": "^13.0.0",
 | 
			
		||||
        "turnstile-types": "^1.2.3",
 | 
			
		||||
        "typescript": "^5.6.2",
 | 
			
		||||
        "typescript-eslint": "^8.8.0",
 | 
			
		||||
@ -118,10 +156,6 @@
 | 
			
		||||
        "vite-tsconfig-paths": "^5.0.1",
 | 
			
		||||
        "wireit": "^0.14.9"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20"
 | 
			
		||||
    },
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "optionalDependencies": {
 | 
			
		||||
        "@esbuild/darwin-arm64": "^0.24.0",
 | 
			
		||||
        "@esbuild/linux-amd64": "^0.18.11",
 | 
			
		||||
@ -130,48 +164,6 @@
 | 
			
		||||
        "@rollup/rollup-linux-arm64-gnu": "4.23.0",
 | 
			
		||||
        "@rollup/rollup-linux-x64-gnu": "4.23.0"
 | 
			
		||||
    },
 | 
			
		||||
    "overrides": {
 | 
			
		||||
        "rapidoc": {
 | 
			
		||||
            "@apitools/openapi-parser@": "0.0.37"
 | 
			
		||||
        },
 | 
			
		||||
        "chromedriver": {
 | 
			
		||||
            "axios": "^1.8.4"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "prettier": "@goauthentik/prettier-config",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "wireit",
 | 
			
		||||
        "build-locales": "wireit",
 | 
			
		||||
        "build-locales:build": "wireit",
 | 
			
		||||
        "build-proxy": "wireit",
 | 
			
		||||
        "build:sfe": "wireit",
 | 
			
		||||
        "esbuild:watch": "node scripts/build-web.mjs --watch",
 | 
			
		||||
        "extract-locales": "wireit",
 | 
			
		||||
        "format": "wireit",
 | 
			
		||||
        "lint": "wireit",
 | 
			
		||||
        "lint:imports": "wireit",
 | 
			
		||||
        "lint:lockfile": "wireit",
 | 
			
		||||
        "lint:nightmare": "wireit",
 | 
			
		||||
        "lint:package": "wireit",
 | 
			
		||||
        "lint:precommit": "wireit",
 | 
			
		||||
        "lint:types": "wireit",
 | 
			
		||||
        "lit-analyse": "wireit",
 | 
			
		||||
        "postinstall": "bash scripts/patch-spotlight.sh",
 | 
			
		||||
        "precommit": "wireit",
 | 
			
		||||
        "prettier": "wireit",
 | 
			
		||||
        "prettier-check": "wireit",
 | 
			
		||||
        "pseudolocalize": "wireit",
 | 
			
		||||
        "storybook": "storybook dev -p 6006",
 | 
			
		||||
        "storybook:build": "wireit",
 | 
			
		||||
        "test": "wireit",
 | 
			
		||||
        "test:e2e": "wireit",
 | 
			
		||||
        "test:e2e:watch": "wireit",
 | 
			
		||||
        "test:watch": "wireit",
 | 
			
		||||
        "tsc": "wireit",
 | 
			
		||||
        "watch": "run-s build-locales esbuild:watch"
 | 
			
		||||
    },
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "wireit": {
 | 
			
		||||
        "build": {
 | 
			
		||||
            "#comment": [
 | 
			
		||||
@ -248,10 +240,7 @@
 | 
			
		||||
            "command": "lit-localize extract"
 | 
			
		||||
        },
 | 
			
		||||
        "format": {
 | 
			
		||||
            "command": "prettier --write .",
 | 
			
		||||
            "dependencies": [
 | 
			
		||||
                "lint:package"
 | 
			
		||||
            ]
 | 
			
		||||
            "command": "prettier --write ."
 | 
			
		||||
        },
 | 
			
		||||
        "format:packages": {
 | 
			
		||||
            "dependencies": [
 | 
			
		||||
@ -290,9 +279,6 @@
 | 
			
		||||
                "./packages/sfe:lint:lockfile"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "lint:package": {
 | 
			
		||||
            "command": "syncpack format -i '    '"
 | 
			
		||||
        },
 | 
			
		||||
        "lint:nightmare": {
 | 
			
		||||
            "command": "${NODE_RUNNER} ./scripts/eslint.mjs --nightmare",
 | 
			
		||||
            "env": {
 | 
			
		||||
@ -323,7 +309,6 @@
 | 
			
		||||
                "lint:types",
 | 
			
		||||
                "lint:components",
 | 
			
		||||
                "lint:spelling",
 | 
			
		||||
                "lint:package",
 | 
			
		||||
                "lint:lockfile",
 | 
			
		||||
                "lint:lockfiles",
 | 
			
		||||
                "lint:precommit",
 | 
			
		||||
@ -388,8 +373,20 @@
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20"
 | 
			
		||||
    },
 | 
			
		||||
    "workspaces": [
 | 
			
		||||
        ".",
 | 
			
		||||
        "./packages/*"
 | 
			
		||||
    ]
 | 
			
		||||
    ],
 | 
			
		||||
    "prettier": "@goauthentik/prettier-config",
 | 
			
		||||
    "overrides": {
 | 
			
		||||
        "rapidoc": {
 | 
			
		||||
            "@apitools/openapi-parser@": "0.0.37"
 | 
			
		||||
        },
 | 
			
		||||
        "chromedriver": {
 | 
			
		||||
            "axios": "^1.8.4"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,22 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/esbuild-plugin-live-reload",
 | 
			
		||||
    "description": "ESBuild plugin to watch for file changes and trigger client-side reloads.",
 | 
			
		||||
    "version": "1.0.4",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "find-free-ports": "^3.1.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
        "@types/node": "^22.14.1",
 | 
			
		||||
        "esbuild": "^0.25.0",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "typescript": "^5.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
    },
 | 
			
		||||
    "description": "ESBuild plugin to watch for file changes and trigger client-side reloads.",
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "main": "index.js",
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "exports": {
 | 
			
		||||
        "./package.json": "./package.json",
 | 
			
		||||
        ".": {
 | 
			
		||||
@ -32,22 +21,33 @@
 | 
			
		||||
            "import": "./plugin/index.js"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "find-free-ports": "^3.1.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
        "@types/node": "^22.14.1",
 | 
			
		||||
        "esbuild": "^0.25.0",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "typescript": "^5.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "peerDependencies": {
 | 
			
		||||
        "esbuild": "^0.25.0"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
    },
 | 
			
		||||
    "types": "./out/index.d.ts",
 | 
			
		||||
    "files": [
 | 
			
		||||
        "./index.js",
 | 
			
		||||
        "client/**/*",
 | 
			
		||||
        "plugin/**/*",
 | 
			
		||||
        "out/**/*"
 | 
			
		||||
    ],
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "main": "index.js",
 | 
			
		||||
    "peerDependencies": {
 | 
			
		||||
        "esbuild": "^0.25.0"
 | 
			
		||||
    },
 | 
			
		||||
    "prettier": "@goauthentik/prettier-config",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
    },
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "types": "./out/index.d.ts"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,4 +2,3 @@
 | 
			
		||||
 | 
			
		||||
This package contains utility scripts common to all TypeScript and JavaScript packages in the
 | 
			
		||||
`@goauthentik` monorepo.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								web/packages/monorepo/build.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								web/packages/monorepo/build.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Utility functions for building and copying files.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A source environment variable, which can be a string, number, boolean, null, or undefined.
 | 
			
		||||
 * @typedef {string | number | boolean | null | undefined} EnvironmentVariable
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A type helper for serializing environment variables.
 | 
			
		||||
 *
 | 
			
		||||
 * @template {EnvironmentVariable} T
 | 
			
		||||
 * @typedef {T extends string ? `"${T}"` : T} JSONify
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given an object of environment variables, returns a new object with the same keys and values, but
 | 
			
		||||
 * with the values serialized as strings.
 | 
			
		||||
 *
 | 
			
		||||
 * @template {Record<string, EnvironmentVariable>} EnvRecord
 | 
			
		||||
 * @template {string} [Prefix='process.env.']
 | 
			
		||||
 *
 | 
			
		||||
 * @param {EnvRecord} input
 | 
			
		||||
 * @param {Prefix} [prefix='process.env.']
 | 
			
		||||
 *
 | 
			
		||||
 * @returns {{[K in keyof EnvRecord as `${Prefix}${K}`]: JSONify<EnvRecord[K]>}}
 | 
			
		||||
 */
 | 
			
		||||
export function serializeEnvironmentVars(input, prefix = /** @type {Prefix} */ ("process.env.")) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Record<string, string>}
 | 
			
		||||
     */
 | 
			
		||||
    const env = {};
 | 
			
		||||
 | 
			
		||||
    for (const [key, value] of Object.entries(input)) {
 | 
			
		||||
        const namespaceKey = prefix + key;
 | 
			
		||||
 | 
			
		||||
        env[namespaceKey] = JSON.stringify(value || "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return /** @type {any} */ (env);
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +1,9 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file Constants for JavaScript and TypeScript files.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/// <reference types="../../types/global.js" />
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The current Node.js environment, defaulting to "development" when not set.
 | 
			
		||||
 *
 | 
			
		||||
@ -12,6 +13,4 @@
 | 
			
		||||
 * ensure that module tree-shaking works correctly.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
export const NodeEnvironment = /** @type {'development' | 'production'} */ (
 | 
			
		||||
    process.env.NODE_ENV || "development"
 | 
			
		||||
);
 | 
			
		||||
export const NodeEnvironment = process.env.NODE_ENV || "development";
 | 
			
		||||
@ -1,4 +1,7 @@
 | 
			
		||||
/// <reference types="./types/global.js" />
 | 
			
		||||
 | 
			
		||||
export * from "./paths.js";
 | 
			
		||||
export * from "./constants.js";
 | 
			
		||||
export * from "./build.js";
 | 
			
		||||
export * from "./version.js";
 | 
			
		||||
export * from "./scripting.js";
 | 
			
		||||
							
								
								
									
										28
									
								
								web/packages/monorepo/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/packages/monorepo/package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@goauthentik/monorepo",
 | 
			
		||||
    "version": "1.0.0",
 | 
			
		||||
    "description": "Utilities for the authentik monorepo.",
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "main": "index.js",
 | 
			
		||||
    "type": "module",
 | 
			
		||||
    "exports": {
 | 
			
		||||
        "./package.json": "./package.json",
 | 
			
		||||
        ".": {
 | 
			
		||||
            "types": "./out/index.d.ts",
 | 
			
		||||
            "import": "./index.js"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@goauthentik/prettier-config": "^1.0.4",
 | 
			
		||||
        "@goauthentik/tsconfig": "^1.0.4",
 | 
			
		||||
        "@types/node": "^22.14.1",
 | 
			
		||||
        "prettier": "^3.3.3",
 | 
			
		||||
        "typescript": "^5.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=20.11"
 | 
			
		||||
    },
 | 
			
		||||
    "types": "./out/index.d.ts",
 | 
			
		||||
    "prettier": "@goauthentik/prettier-config"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								web/packages/monorepo/paths.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								web/packages/monorepo/paths.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
import { createRequire } from "node:module";
 | 
			
		||||
import { dirname, join, resolve } from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
 | 
			
		||||
const relativeDirname = dirname(fileURLToPath(import.meta.url));
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {'~authentik'} MonoRepoRoot
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The root of the authentik monorepo.
 | 
			
		||||
 */
 | 
			
		||||
// TODO: Revise when this package is moved to the monorepo's `packages/monorepo` directory.
 | 
			
		||||
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (
 | 
			
		||||
    resolve(relativeDirname, "..", "..", "..")
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const require = createRequire(import.meta.url);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resolve a package name to its location in the monorepo to the single node_modules directory.
 | 
			
		||||
 * @param {string} packageName
 | 
			
		||||
 *
 | 
			
		||||
 * @returns {string} The resolved path to the package.
 | 
			
		||||
 * @throws {Error} If the package cannot be resolved.
 | 
			
		||||
 */
 | 
			
		||||
export function resolvePackage(packageName) {
 | 
			
		||||
    const relativePackageJSONPath = join(packageName, "package.json");
 | 
			
		||||
 | 
			
		||||
    /** @type {string} */
 | 
			
		||||
    let absolutePackageJSONPath;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        absolutePackageJSONPath = require.resolve(relativePackageJSONPath);
 | 
			
		||||
    } catch (cause) {
 | 
			
		||||
        const error = new Error(`Failed to resolve package "${packageName}"`);
 | 
			
		||||
 | 
			
		||||
        error.cause = cause;
 | 
			
		||||
 | 
			
		||||
        throw error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return dirname(absolutePackageJSONPath);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								web/packages/monorepo/types/global.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								web/packages/monorepo/types/global.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
declare module "process" {
 | 
			
		||||
    global {
 | 
			
		||||
        namespace NodeJS {
 | 
			
		||||
            interface ProcessEnv {
 | 
			
		||||
                /**
 | 
			
		||||
                 * An environment variable used to determine
 | 
			
		||||
                 * whether Node.js is running in production mode.
 | 
			
		||||
                 *
 | 
			
		||||
                 * @see {@link https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production | The difference between development and production}
 | 
			
		||||
                 */
 | 
			
		||||
                NODE_ENV?: "production" | "development";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { execSync } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
import PackageJSON from "../../package.json" with { type: "json" };
 | 
			
		||||
import PackageJSON from "../../../package.json" with { type: "json" };
 | 
			
		||||
import { MonoRepoRoot } from "./paths.js";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -47,7 +47,16 @@ class SimpleFlowExecutor {
 | 
			
		||||
        return `${ak().api.base}api/v3/flows/executor/${this.flowSlug}/?query=${encodeURIComponent(window.location.search.substring(1))}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    loading() {
 | 
			
		||||
        this.container.innerHTML = `<div class="d-flex justify-content-center">
 | 
			
		||||
            <div class="spinner-border spinner-border-md" role="status">
 | 
			
		||||
                <span class="sr-only">Loading...</span>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    start() {
 | 
			
		||||
        this.loading();
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            type: "GET",
 | 
			
		||||
            url: this.apiURL,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										78
									
								
								web/paths.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								web/paths.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
import { dirname, resolve } from "node:path";
 | 
			
		||||
import { fileURLToPath } from "node:url";
 | 
			
		||||
 | 
			
		||||
const relativeDirname = dirname(fileURLToPath(import.meta.url));
 | 
			
		||||
 | 
			
		||||
//#region Base paths
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {'@goauthentik/web'} WebPackageIdentifier
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The root of the web package.
 | 
			
		||||
 */
 | 
			
		||||
export const PackageRoot = /** @type {WebPackageIdentifier} */ (resolve(relativeDirname));
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The name of the distribution directory.
 | 
			
		||||
 */
 | 
			
		||||
export const DistDirectoryName = "dist";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Path to the web package's distribution directory.
 | 
			
		||||
 *
 | 
			
		||||
 * This is where the built files are located after running the build process.
 | 
			
		||||
 */
 | 
			
		||||
export const DistDirectory = /** @type {`${WebPackageIdentifier}/${DistDirectoryName}`} */ (
 | 
			
		||||
    resolve(relativeDirname, DistDirectoryName)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
//#endregion
 | 
			
		||||
 | 
			
		||||
//#region Entry points
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {{ in: string, out: string }} EntryPointTarget
 | 
			
		||||
 *
 | 
			
		||||
 * ESBuild entrypoint target.
 | 
			
		||||
 * Matches the type defined in the ESBuild context.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Entry points available for building.
 | 
			
		||||
 *
 | 
			
		||||
 * @satisfies {Record<string, EntryPointTarget>}
 | 
			
		||||
 */
 | 
			
		||||
export const EntryPoint = /** @type {const} */ ({
 | 
			
		||||
    Admin: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "admin", "AdminInterface", "index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "admin", "AdminInterface"),
 | 
			
		||||
    },
 | 
			
		||||
    User: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "user", "index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "user", "UserInterface"),
 | 
			
		||||
    },
 | 
			
		||||
    Flow: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "flow", "index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "flow", "FlowInterface"),
 | 
			
		||||
    },
 | 
			
		||||
    Standalone: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "standalone", "api-browser/index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "standalone", "api-browser", "index"),
 | 
			
		||||
    },
 | 
			
		||||
    StandaloneLoading: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "standalone", "loading/index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "standalone", "loading", "index"),
 | 
			
		||||
    },
 | 
			
		||||
    RAC: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "rac", "index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "rac", "index"),
 | 
			
		||||
    },
 | 
			
		||||
    Polyfill: {
 | 
			
		||||
        in: resolve(PackageRoot, "src", "polyfill", "index.entrypoint.ts"),
 | 
			
		||||
        out: resolve(DistDirectory, "poly"),
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
//#endregion
 | 
			
		||||
@ -4,138 +4,86 @@
 | 
			
		||||
 * @import { BuildOptions } from "esbuild";
 | 
			
		||||
 */
 | 
			
		||||
import { liveReloadPlugin } from "@goauthentik/esbuild-plugin-live-reload/plugin";
 | 
			
		||||
import { execFileSync } from "child_process";
 | 
			
		||||
import {
 | 
			
		||||
    MonoRepoRoot,
 | 
			
		||||
    NodeEnvironment,
 | 
			
		||||
    readBuildIdentifier,
 | 
			
		||||
    resolvePackage,
 | 
			
		||||
    serializeEnvironmentVars,
 | 
			
		||||
} from "@goauthentik/monorepo";
 | 
			
		||||
import { DistDirectory, DistDirectoryName, EntryPoint, PackageRoot } from "@goauthentik/web/paths";
 | 
			
		||||
import { deepmerge } from "deepmerge-ts";
 | 
			
		||||
import esbuild from "esbuild";
 | 
			
		||||
import copy from "esbuild-plugin-copy";
 | 
			
		||||
import { polyfillNode } from "esbuild-plugin-polyfill-node";
 | 
			
		||||
import { copyFileSync, mkdirSync, readFileSync, statSync } from "fs";
 | 
			
		||||
import { globSync } from "glob";
 | 
			
		||||
import * as path from "path";
 | 
			
		||||
import { cwd } from "process";
 | 
			
		||||
import process from "process";
 | 
			
		||||
import { fileURLToPath } from "url";
 | 
			
		||||
import * as fs from "node:fs/promises";
 | 
			
		||||
import * as path from "node:path";
 | 
			
		||||
 | 
			
		||||
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
 | 
			
		||||
 | 
			
		||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
 | 
			
		||||
let authentikProjectRoot = path.join(__dirname, "..", "..");
 | 
			
		||||
const logPrefix = "[Build]";
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
    // Use the package.json file in the root folder, as it has the current version information.
 | 
			
		||||
    authentikProjectRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
 | 
			
		||||
        encoding: "utf8",
 | 
			
		||||
    }).replace("\n", "");
 | 
			
		||||
} catch (_error) {
 | 
			
		||||
    // We probably don't have a .git folder, which could happen in container builds.
 | 
			
		||||
}
 | 
			
		||||
const definitions = serializeEnvironmentVars({
 | 
			
		||||
    NODE_ENV: NodeEnvironment,
 | 
			
		||||
    CWD: process.cwd(),
 | 
			
		||||
    AK_API_BASE_PATH: process.env.AK_API_BASE_PATH,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const packageJSONPath = path.join(authentikProjectRoot, "./package.json");
 | 
			
		||||
const rootPackage = JSON.parse(readFileSync(packageJSONPath, "utf8"));
 | 
			
		||||
 | 
			
		||||
const NODE_ENV = process.env.NODE_ENV || "development";
 | 
			
		||||
const AK_API_BASE_PATH = process.env.AK_API_BASE_PATH || "";
 | 
			
		||||
 | 
			
		||||
const environmentVars = new Map([
 | 
			
		||||
    ["NODE_ENV", NODE_ENV],
 | 
			
		||||
    ["CWD", cwd()],
 | 
			
		||||
    ["AK_API_BASE_PATH", AK_API_BASE_PATH],
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
const definitions = Object.fromEntries(
 | 
			
		||||
    Array.from(environmentVars).map(([key, value]) => {
 | 
			
		||||
        return [`process.env.${key}`, JSON.stringify(value)];
 | 
			
		||||
    }),
 | 
			
		||||
);
 | 
			
		||||
const patternflyPath = resolvePackage("@patternfly/patternfly");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * All is magic is just to make sure the assets are copied into the right places. This is a very
 | 
			
		||||
 * stripped down version of what the rollup-copy-plugin does, without any of the features we don't
 | 
			
		||||
 * use, and using globSync instead of globby since we already had globSync lying around thanks to
 | 
			
		||||
 * Typescript. If there's a third argument in an array entry, it's used to replace the internal path
 | 
			
		||||
 * before concatenating it all together as the destination target.
 | 
			
		||||
 * @type {Array<[string, string, string?]>}
 | 
			
		||||
 */
 | 
			
		||||
const assetsFileMappings = [
 | 
			
		||||
    ["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
 | 
			
		||||
    ["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
 | 
			
		||||
    ["src/common/styles/**", "."],
 | 
			
		||||
    ["src/assets/images/**", "./assets/images"],
 | 
			
		||||
    ["./icons/*", "./assets/icons"],
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {string} filePath
 | 
			
		||||
 */
 | 
			
		||||
const isFile = (filePath) => statSync(filePath).isFile();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {string} src Source file
 | 
			
		||||
 * @param {string} dest Destination folder
 | 
			
		||||
 * @param {string} [strip] Path to strip from the source file
 | 
			
		||||
 */
 | 
			
		||||
function nameCopyTarget(src, dest, strip) {
 | 
			
		||||
    const target = path.join(dest, strip ? src.replace(strip, "") : path.parse(src).base);
 | 
			
		||||
    return [src, target];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for (const [source, rawdest, strip] of assetsFileMappings) {
 | 
			
		||||
    const matchedPaths = globSync(source);
 | 
			
		||||
    const dest = path.join("dist", rawdest);
 | 
			
		||||
 | 
			
		||||
    const copyTargets = matchedPaths.map((path) => nameCopyTarget(path, dest, strip));
 | 
			
		||||
 | 
			
		||||
    for (const [src, dest] of copyTargets) {
 | 
			
		||||
        if (isFile(src)) {
 | 
			
		||||
            mkdirSync(path.dirname(dest), { recursive: true });
 | 
			
		||||
            copyFileSync(src, dest);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {[source: string, destination: string]} EntryPoint
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This starts the definitions used for esbuild: Our targets, our arguments, the function for
 | 
			
		||||
 * running a build, and three options for building: watching, building, and building the proxy.
 | 
			
		||||
 * Ordered by largest to smallest interface to build even faster
 | 
			
		||||
 *
 | 
			
		||||
 * @type {EntryPoint[]}
 | 
			
		||||
 */
 | 
			
		||||
const entryPoints = [
 | 
			
		||||
    ["admin/AdminInterface/AdminInterface.ts", "admin"],
 | 
			
		||||
    ["user/UserInterface.ts", "user"],
 | 
			
		||||
    ["flow/FlowInterface.ts", "flow"],
 | 
			
		||||
    ["standalone/api-browser/index.ts", "standalone/api-browser"],
 | 
			
		||||
    ["rac/index.ts", "rac"],
 | 
			
		||||
    ["standalone/loading/index.ts", "standalone/loading"],
 | 
			
		||||
    ["polyfill/poly.ts", "."],
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @type {import("esbuild").BuildOptions}
 | 
			
		||||
 * @type {Readonly<BuildOptions>}
 | 
			
		||||
 */
 | 
			
		||||
const BASE_ESBUILD_OPTIONS = {
 | 
			
		||||
    entryNames: `[dir]/[name]-${readBuildIdentifier()}`,
 | 
			
		||||
    chunkNames: "[dir]/chunks/[name]-[hash]",
 | 
			
		||||
    assetNames: "assets/[dir]/[name]-[hash]",
 | 
			
		||||
    publicPath: path.join("/static", DistDirectoryName),
 | 
			
		||||
    outdir: DistDirectory,
 | 
			
		||||
    bundle: true,
 | 
			
		||||
    write: true,
 | 
			
		||||
    sourcemap: true,
 | 
			
		||||
    minify: NODE_ENV === "production",
 | 
			
		||||
    minify: NodeEnvironment === "production",
 | 
			
		||||
    legalComments: "external",
 | 
			
		||||
    splitting: true,
 | 
			
		||||
    treeShaking: true,
 | 
			
		||||
    external: ["*.woff", "*.woff2"],
 | 
			
		||||
    tsconfig: path.resolve(__dirname, "..", "tsconfig.build.json"),
 | 
			
		||||
    tsconfig: path.resolve(PackageRoot, "tsconfig.build.json"),
 | 
			
		||||
    loader: {
 | 
			
		||||
        ".css": "text",
 | 
			
		||||
    },
 | 
			
		||||
    plugins: [
 | 
			
		||||
        copy({
 | 
			
		||||
            assets: [
 | 
			
		||||
                {
 | 
			
		||||
                    from: path.join(patternflyPath, "patternfly.min.css"),
 | 
			
		||||
                    to: ".",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    from: path.join(patternflyPath, "assets", "**"),
 | 
			
		||||
                    to: "./assets",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    from: path.resolve(PackageRoot, "src", "common", "styles", "**"),
 | 
			
		||||
                    to: ".",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    from: path.resolve(PackageRoot, "src", "assets", "images", "**"),
 | 
			
		||||
                    to: "./assets/images",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    from: path.resolve(PackageRoot, "icons", "*"),
 | 
			
		||||
                    to: "./assets/icons",
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        }),
 | 
			
		||||
        polyfillNode({
 | 
			
		||||
            polyfills: {
 | 
			
		||||
                path: true,
 | 
			
		||||
            },
 | 
			
		||||
        }),
 | 
			
		||||
        mdxPlugin({
 | 
			
		||||
            root: authentikProjectRoot,
 | 
			
		||||
            root: MonoRepoRoot,
 | 
			
		||||
        }),
 | 
			
		||||
    ],
 | 
			
		||||
    define: definitions,
 | 
			
		||||
@ -151,69 +99,43 @@ const BASE_ESBUILD_OPTIONS = {
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a version ID for the build.
 | 
			
		||||
 * @returns {string}
 | 
			
		||||
 */
 | 
			
		||||
function composeVersionID() {
 | 
			
		||||
    const { version } = rootPackage;
 | 
			
		||||
    const buildHash = process.env.GIT_BUILD_HASH;
 | 
			
		||||
async function cleanDistDirectory() {
 | 
			
		||||
    const timerLabel = `${logPrefix} ♻️ Cleaning previous builds...`;
 | 
			
		||||
 | 
			
		||||
    if (buildHash) {
 | 
			
		||||
        return `${version}+${buildHash}`;
 | 
			
		||||
    }
 | 
			
		||||
    console.time(timerLabel);
 | 
			
		||||
 | 
			
		||||
    return version;
 | 
			
		||||
    await fs.rm(DistDirectory, {
 | 
			
		||||
        recursive: true,
 | 
			
		||||
        force: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await fs.mkdir(DistDirectory, {
 | 
			
		||||
        recursive: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    console.timeEnd(timerLabel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Build a single entry point.
 | 
			
		||||
 * Creates an ESBuild options, extending the base options with the given overrides.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {EntryPoint} buildTarget
 | 
			
		||||
 * @param {Partial<esbuild.BuildOptions>} [overrides]
 | 
			
		||||
 * @throws {Error} on build failure
 | 
			
		||||
 * @param {BuildOptions} overrides
 | 
			
		||||
 * @returns {BuildOptions}
 | 
			
		||||
 */
 | 
			
		||||
function createEntryPointOptions([source, dest], overrides = {}) {
 | 
			
		||||
    const outdir = path.join(__dirname, "..", "dist", dest);
 | 
			
		||||
 | 
			
		||||
export function createESBuildOptions(overrides) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {esbuild.BuildOptions}
 | 
			
		||||
     * @type {BuildOptions}
 | 
			
		||||
     */
 | 
			
		||||
    const mergedOptions = deepmerge(BASE_ESBUILD_OPTIONS, overrides);
 | 
			
		||||
 | 
			
		||||
    const entryPointConfig = {
 | 
			
		||||
        entryPoints: [`./src/${source}`],
 | 
			
		||||
        entryNames: `[dir]/[name]-${composeVersionID()}`,
 | 
			
		||||
        publicPath: path.join("/static", "dist", dest),
 | 
			
		||||
        outdir,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {esbuild.BuildOptions}
 | 
			
		||||
     */
 | 
			
		||||
    const mergedConfig = deepmerge(BASE_ESBUILD_OPTIONS, entryPointConfig, overrides);
 | 
			
		||||
 | 
			
		||||
    return mergedConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Build all entry points in parallel.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {EntryPoint[]} entryPoints
 | 
			
		||||
 * @returns {Promise<esbuild.BuildResult[]>}
 | 
			
		||||
 */
 | 
			
		||||
async function buildParallel(entryPoints) {
 | 
			
		||||
    return Promise.all(
 | 
			
		||||
        entryPoints.map((entryPoint) => {
 | 
			
		||||
            return esbuild.build(createEntryPointOptions(entryPoint));
 | 
			
		||||
        }),
 | 
			
		||||
    );
 | 
			
		||||
    return mergedOptions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function doHelp() {
 | 
			
		||||
    console.log(`Build the authentik UI
 | 
			
		||||
 | 
			
		||||
        options:
 | 
			
		||||
            -w, --watch: Build all ${entryPoints.length} interfaces
 | 
			
		||||
            -w, --watch: Build all interfaces
 | 
			
		||||
            -p, --proxy: Build only the polyfills and the loading application
 | 
			
		||||
            -h, --help: This help message
 | 
			
		||||
`);
 | 
			
		||||
@ -222,27 +144,29 @@ function doHelp() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function doWatch() {
 | 
			
		||||
    console.log("Watching all entry points...");
 | 
			
		||||
    console.group(`${logPrefix} 🤖 Watching entry points`);
 | 
			
		||||
 | 
			
		||||
    const buildContexts = await Promise.all(
 | 
			
		||||
        entryPoints.map((entryPoint) => {
 | 
			
		||||
            return esbuild.context(
 | 
			
		||||
                createEntryPointOptions(entryPoint, {
 | 
			
		||||
                    define: definitions,
 | 
			
		||||
    const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
 | 
			
		||||
        console.log(entrypointID);
 | 
			
		||||
 | 
			
		||||
        return target;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    console.groupEnd();
 | 
			
		||||
 | 
			
		||||
    const buildOptions = createESBuildOptions({
 | 
			
		||||
        entryPoints,
 | 
			
		||||
        plugins: [
 | 
			
		||||
            liveReloadPlugin({
 | 
			
		||||
                            logPrefix: `Build Observer (${entryPoint[1]})`,
 | 
			
		||||
                            relativeRoot: path.join(__dirname, ".."),
 | 
			
		||||
                relativeRoot: PackageRoot,
 | 
			
		||||
            }),
 | 
			
		||||
        ],
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        }),
 | 
			
		||||
    );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await Promise.all(buildContexts.map((context) => context.rebuild()));
 | 
			
		||||
    const buildContext = await esbuild.context(buildOptions);
 | 
			
		||||
 | 
			
		||||
    await Promise.allSettled(buildContexts.map((context) => context.watch()));
 | 
			
		||||
    await buildContext.rebuild();
 | 
			
		||||
    await buildContext.watch();
 | 
			
		||||
 | 
			
		||||
    return /** @type {Promise<void>} */ (
 | 
			
		||||
        new Promise((resolve) => {
 | 
			
		||||
@ -254,15 +178,34 @@ async function doWatch() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function doBuild() {
 | 
			
		||||
    console.log("Building all entry points");
 | 
			
		||||
    console.group(`${logPrefix} 🚀 Building entry points:`);
 | 
			
		||||
 | 
			
		||||
    return buildParallel(entryPoints);
 | 
			
		||||
    const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
 | 
			
		||||
        console.log(entrypointID);
 | 
			
		||||
 | 
			
		||||
        return target;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    console.groupEnd();
 | 
			
		||||
 | 
			
		||||
    const buildOptions = createESBuildOptions({
 | 
			
		||||
        entryPoints,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await esbuild.build(buildOptions);
 | 
			
		||||
 | 
			
		||||
    console.log("Build complete");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function doProxy() {
 | 
			
		||||
    return buildParallel(
 | 
			
		||||
        entryPoints.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
 | 
			
		||||
    );
 | 
			
		||||
    const entryPoints = [EntryPoint.StandaloneLoading];
 | 
			
		||||
 | 
			
		||||
    const buildOptions = createESBuildOptions({
 | 
			
		||||
        entryPoints,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await esbuild.build(buildOptions);
 | 
			
		||||
    console.log("Proxy build complete");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function delegateCommand() {
 | 
			
		||||
@ -284,7 +227,10 @@ async function delegateCommand() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
await delegateCommand()
 | 
			
		||||
await cleanDistDirectory()
 | 
			
		||||
    // ---
 | 
			
		||||
    .then(() =>
 | 
			
		||||
        delegateCommand()
 | 
			
		||||
            .then(() => {
 | 
			
		||||
                console.log("Build complete");
 | 
			
		||||
                process.exit(0);
 | 
			
		||||
@ -292,4 +238,5 @@ await delegateCommand()
 | 
			
		||||
            .catch((error) => {
 | 
			
		||||
                console.error(error);
 | 
			
		||||
                process.exit(1);
 | 
			
		||||
    });
 | 
			
		||||
            }),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { VERSION } from "@goauthentik/common/constants";
 | 
			
		||||
import { globalAK } from "@goauthentik/common/global";
 | 
			
		||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
 | 
			
		||||
import "@goauthentik/elements/EmptyState";
 | 
			
		||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
 | 
			
		||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
 | 
			
		||||
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
 | 
			
		||||
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
import { TemplateResult, css, html } from "lit";
 | 
			
		||||
 | 
			
		||||
@ -1,132 +1,77 @@
 | 
			
		||||
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
import { AKElement } from "@goauthentik/elements/Base";
 | 
			
		||||
import {
 | 
			
		||||
    CapabilitiesEnum,
 | 
			
		||||
    WithCapabilitiesConfig,
 | 
			
		||||
} from "@goauthentik/elements/Interface/capabilitiesProvider";
 | 
			
		||||
import { WithVersion } from "@goauthentik/elements/Interface/versionProvider";
 | 
			
		||||
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
 | 
			
		||||
import { getRootStyle } from "@goauthentik/elements/utils/getRootStyle";
 | 
			
		||||
import { spread } from "@open-wc/lit-helpers";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
import { TemplateResult, html, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators.js";
 | 
			
		||||
import { map } from "lit/directives/map.js";
 | 
			
		||||
import { repeat } from "lit/directives/repeat.js";
 | 
			
		||||
 | 
			
		||||
import { UiThemeEnum } from "@goauthentik/api";
 | 
			
		||||
import type { SessionUser, UserSelf } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
@customElement("ak-admin-sidebar")
 | 
			
		||||
export class AkAdminSidebar extends WithCapabilitiesConfig(WithVersion(AKElement)) {
 | 
			
		||||
    @property({ type: Boolean, reflect: true })
 | 
			
		||||
    open = true;
 | 
			
		||||
 | 
			
		||||
    @state()
 | 
			
		||||
    impersonation: UserSelf["username"] | null = null;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
        me().then((user: SessionUser) => {
 | 
			
		||||
            this.impersonation = user.original ? user.user.username : null;
 | 
			
		||||
        });
 | 
			
		||||
        this.toggleOpen = this.toggleOpen.bind(this);
 | 
			
		||||
        this.checkWidth = this.checkWidth.bind(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This has to be a bound method so the event listener can be removed on disconnection as
 | 
			
		||||
    // needed.
 | 
			
		||||
    toggleOpen() {
 | 
			
		||||
        this.open = !this.open;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    checkWidth() {
 | 
			
		||||
        // This works just fine, but it assumes that the `--ak-sidebar--minimum-auto-width` is in
 | 
			
		||||
        // REMs. If that changes, this code will have to be adjusted as well.
 | 
			
		||||
        const minWidth =
 | 
			
		||||
            parseFloat(getRootStyle("--ak-sidebar--minimum-auto-width")) *
 | 
			
		||||
            parseFloat(getRootStyle("font-size"));
 | 
			
		||||
        this.open = window.innerWidth >= minWidth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connectedCallback() {
 | 
			
		||||
        super.connectedCallback();
 | 
			
		||||
        window.addEventListener(EVENT_SIDEBAR_TOGGLE, this.toggleOpen);
 | 
			
		||||
        window.addEventListener("resize", this.checkWidth);
 | 
			
		||||
        // After connecting to the DOM, we can now perform this check to see if the sidebar should
 | 
			
		||||
        // be open by default.
 | 
			
		||||
        this.checkWidth();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The symmetry (☟, ☝) here is critical in that you want to start adding these handlers after
 | 
			
		||||
    // connection, and removing them before disconnection.
 | 
			
		||||
 | 
			
		||||
    disconnectedCallback() {
 | 
			
		||||
        window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.toggleOpen);
 | 
			
		||||
        window.removeEventListener("resize", this.checkWidth);
 | 
			
		||||
        super.disconnectedCallback();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        return html`
 | 
			
		||||
            <ak-sidebar
 | 
			
		||||
                class="pf-c-page__sidebar ${this.open ? "pf-m-expanded" : "pf-m-collapsed"} ${this
 | 
			
		||||
                    .activeTheme === UiThemeEnum.Light
 | 
			
		||||
                    ? "pf-m-light"
 | 
			
		||||
                    : ""}"
 | 
			
		||||
            >
 | 
			
		||||
                ${this.renderSidebarItems()}
 | 
			
		||||
            </ak-sidebar>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updated() {
 | 
			
		||||
        // This is permissible as`:host.classList` is not one of the properties Lit uses as a
 | 
			
		||||
        // scheduling trigger. This sort of shenanigans can trigger an loop, in that it will trigger
 | 
			
		||||
        // a browser reflow, which may trigger some other styling the application is monitoring,
 | 
			
		||||
        // triggering a re-render which triggers a browser reflow, ad infinitum. But we've been
 | 
			
		||||
        // living with that since jQuery, and it's both well-known and fortunately rare.
 | 
			
		||||
 | 
			
		||||
        // eslint-disable-next-line wc/no-self-class
 | 
			
		||||
        this.classList.remove("pf-m-expanded", "pf-m-collapsed");
 | 
			
		||||
        // eslint-disable-next-line wc/no-self-class
 | 
			
		||||
        this.classList.add(this.open ? "pf-m-expanded" : "pf-m-collapsed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    renderSidebarItems(): TemplateResult {
 | 
			
		||||
        // The second attribute type is of string[] to help with the 'activeWhen' control, which was
 | 
			
		||||
        // commonplace and singular enough to merit its own handler.
 | 
			
		||||
        type SidebarEntry = [
 | 
			
		||||
// The second attribute type is of string[] to help with the 'activeWhen' control, which was
 | 
			
		||||
// commonplace and singular enough to merit its own handler.
 | 
			
		||||
type SidebarEntry = [
 | 
			
		||||
    path: string | null,
 | 
			
		||||
    label: string,
 | 
			
		||||
    attributes?: Record<string, any> | string[] | null, // eslint-disable-line
 | 
			
		||||
    children?: SidebarEntry[],
 | 
			
		||||
        ];
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
        // prettier-ignore
 | 
			
		||||
        const sidebarContent: SidebarEntry[] = [
 | 
			
		||||
/**
 | 
			
		||||
 * Recursively renders a sidebar entry.
 | 
			
		||||
 */
 | 
			
		||||
export function renderSidebarItem([
 | 
			
		||||
    path,
 | 
			
		||||
    label,
 | 
			
		||||
    attributes,
 | 
			
		||||
    children,
 | 
			
		||||
]: SidebarEntry): TemplateResult {
 | 
			
		||||
    const properties = Array.isArray(attributes)
 | 
			
		||||
        ? { ".activeWhen": attributes }
 | 
			
		||||
        : (attributes ?? {});
 | 
			
		||||
 | 
			
		||||
    if (path) {
 | 
			
		||||
        properties.path = path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return html`<ak-sidebar-item ${spread(properties)}>
 | 
			
		||||
        ${label ? html`<span slot="label">${label}</span>` : nothing}
 | 
			
		||||
        ${children ? renderSidebarItems(children) : nothing}
 | 
			
		||||
    </ak-sidebar-item>`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Recursively renders a collection of sidebar entries.
 | 
			
		||||
 */
 | 
			
		||||
export function renderSidebarItems(entries: readonly SidebarEntry[]) {
 | 
			
		||||
    return repeat(entries, ([path, label]) => path || label, renderSidebarItem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// prettier-ignore
 | 
			
		||||
export const AdminSidebarEntries: readonly SidebarEntry[] = [
 | 
			
		||||
    [null, msg("Dashboards"), { "?expanded": true }, [
 | 
			
		||||
        ["/administration/overview", msg("Overview")],
 | 
			
		||||
        ["/administration/dashboard/users", msg("User Statistics")],
 | 
			
		||||
                ["/administration/system-tasks", msg("System Tasks")]]],
 | 
			
		||||
        ["/administration/system-tasks", msg("System Tasks")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("Applications"), null, [
 | 
			
		||||
        ["/core/applications", msg("Applications"), [`^/core/applications/(?<slug>${SLUG_REGEX})$`]],
 | 
			
		||||
        ["/core/providers", msg("Providers"), [`^/core/providers/(?<id>${ID_REGEX})$`]],
 | 
			
		||||
                ["/outpost/outposts", msg("Outposts")]]],
 | 
			
		||||
        ["/outpost/outposts", msg("Outposts")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("Events"), null, [
 | 
			
		||||
        ["/events/log", msg("Logs"), [`^/events/log/(?<id>${UUID_REGEX})$`]],
 | 
			
		||||
        ["/events/rules", msg("Notification Rules")],
 | 
			
		||||
                ["/events/transports", msg("Notification Transports")]]],
 | 
			
		||||
        ["/events/transports", msg("Notification Transports")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("Customization"), null, [
 | 
			
		||||
        ["/policy/policies", msg("Policies")],
 | 
			
		||||
        ["/core/property-mappings", msg("Property Mappings")],
 | 
			
		||||
        ["/blueprints/instances", msg("Blueprints")],
 | 
			
		||||
                ["/policy/reputation", msg("Reputation scores")]]],
 | 
			
		||||
        ["/policy/reputation", msg("Reputation scores")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("Flows and Stages"), null, [
 | 
			
		||||
        ["/flow/flows", msg("Flows"), [`^/flow/flows/(?<slug>${SLUG_REGEX})$`]],
 | 
			
		||||
        ["/flow/stages", msg("Stages")],
 | 
			
		||||
                ["/flow/stages/prompts", msg("Prompts")]]],
 | 
			
		||||
        ["/flow/stages/prompts", msg("Prompts")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("Directory"), null, [
 | 
			
		||||
        ["/identity/users", msg("Users"), [`^/identity/users/(?<id>${ID_REGEX})$`]],
 | 
			
		||||
        ["/identity/groups", msg("Groups"), [`^/identity/groups/(?<id>${UUID_REGEX})$`]],
 | 
			
		||||
@ -134,53 +79,19 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(WithVersion(AKElement
 | 
			
		||||
        ["/identity/initial-permissions", msg("Initial Permissions"), [`^/identity/initial-permissions/(?<id>${ID_REGEX})$`]],
 | 
			
		||||
        ["/core/sources", msg("Federation and Social login"), [`^/core/sources/(?<slug>${SLUG_REGEX})$`]],
 | 
			
		||||
        ["/core/tokens", msg("Tokens and App passwords")],
 | 
			
		||||
                ["/flow/stages/invitations", msg("Invitations")]]],
 | 
			
		||||
        ["/flow/stages/invitations", msg("Invitations")]]
 | 
			
		||||
    ],
 | 
			
		||||
    [null, msg("System"), null, [
 | 
			
		||||
        ["/core/brands", msg("Brands")],
 | 
			
		||||
        ["/crypto/certificates", msg("Certificates")],
 | 
			
		||||
        ["/outpost/integrations", msg("Outpost Integrations")],
 | 
			
		||||
                ["/admin/settings", msg("Settings")]]],
 | 
			
		||||
        ];
 | 
			
		||||
        ["/admin/settings", msg("Settings")]]
 | 
			
		||||
    ],
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
        // Typescript requires the type here to correctly type the recursive path
 | 
			
		||||
        type SidebarRenderer = (_: SidebarEntry) => TemplateResult;
 | 
			
		||||
 | 
			
		||||
        const renderOneSidebarItem: SidebarRenderer = ([path, label, attributes, children]) => {
 | 
			
		||||
            const properties = Array.isArray(attributes)
 | 
			
		||||
                ? { ".activeWhen": attributes }
 | 
			
		||||
                : (attributes ?? {});
 | 
			
		||||
            if (path) {
 | 
			
		||||
                properties.path = path;
 | 
			
		||||
            }
 | 
			
		||||
            return html`<ak-sidebar-item ${spread(properties)}>
 | 
			
		||||
                ${label ? html`<span slot="label">${label}</span>` : nothing}
 | 
			
		||||
                ${map(children, renderOneSidebarItem)}
 | 
			
		||||
            </ak-sidebar-item>`;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // prettier-ignore
 | 
			
		||||
        return html`
 | 
			
		||||
            ${map(sidebarContent, renderOneSidebarItem)}
 | 
			
		||||
            ${this.renderEnterpriseMenu()}
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    renderEnterpriseMenu() {
 | 
			
		||||
        return this.can(CapabilitiesEnum.IsEnterprise)
 | 
			
		||||
            ? html`
 | 
			
		||||
                  <ak-sidebar-item>
 | 
			
		||||
                      <span slot="label">${msg("Enterprise")}</span>
 | 
			
		||||
                      <ak-sidebar-item path="/enterprise/licenses">
 | 
			
		||||
                          <span slot="label">${msg("Licenses")}</span>
 | 
			
		||||
                      </ak-sidebar-item>
 | 
			
		||||
                  </ak-sidebar-item>
 | 
			
		||||
              `
 | 
			
		||||
            : nothing;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare global {
 | 
			
		||||
    interface HTMLElementTagNameMap {
 | 
			
		||||
        "ak-admin-sidebar": AkAdminSidebar;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
// prettier-ignore
 | 
			
		||||
export const AdminSidebarEnterpriseEntries: readonly SidebarEntry[] = [
 | 
			
		||||
    [null, msg("Enterprise"), null, [
 | 
			
		||||
        ["/enterprise/licenses", msg("Licenses"), null]
 | 
			
		||||
    ],
 | 
			
		||||
]]
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,17 @@ import { ROUTES } from "@goauthentik/admin/Routes";
 | 
			
		||||
import {
 | 
			
		||||
    EVENT_API_DRAWER_TOGGLE,
 | 
			
		||||
    EVENT_NOTIFICATION_DRAWER_TOGGLE,
 | 
			
		||||
    EVENT_SIDEBAR_TOGGLE,
 | 
			
		||||
} from "@goauthentik/common/constants";
 | 
			
		||||
import { configureSentry } from "@goauthentik/common/sentry";
 | 
			
		||||
import { me } from "@goauthentik/common/users";
 | 
			
		||||
import { WebsocketClient } from "@goauthentik/common/ws";
 | 
			
		||||
import { AuthenticatedInterface } from "@goauthentik/elements/Interface";
 | 
			
		||||
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider.js";
 | 
			
		||||
import "@goauthentik/elements/ak-locale-context";
 | 
			
		||||
import "@goauthentik/elements/banner/EnterpriseStatusBanner";
 | 
			
		||||
import "@goauthentik/elements/banner/EnterpriseStatusBanner";
 | 
			
		||||
import "@goauthentik/elements/banner/VersionBanner";
 | 
			
		||||
import "@goauthentik/elements/banner/VersionBanner";
 | 
			
		||||
import "@goauthentik/elements/messages/MessageContainer";
 | 
			
		||||
import "@goauthentik/elements/messages/MessageContainer";
 | 
			
		||||
@ -21,25 +25,32 @@ import "@goauthentik/elements/router/RouterOutlet";
 | 
			
		||||
import "@goauthentik/elements/sidebar/Sidebar";
 | 
			
		||||
import "@goauthentik/elements/sidebar/SidebarItem";
 | 
			
		||||
 | 
			
		||||
import { CSSResult, TemplateResult, css, html } from "lit";
 | 
			
		||||
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
 | 
			
		||||
import { customElement, property, query, state } from "lit/decorators.js";
 | 
			
		||||
import { classMap } from "lit/directives/class-map.js";
 | 
			
		||||
 | 
			
		||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
 | 
			
		||||
import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
 | 
			
		||||
import PFNav from "@patternfly/patternfly/components/Nav/nav.css";
 | 
			
		||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
 | 
			
		||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
			
		||||
 | 
			
		||||
import { SessionUser, UiThemeEnum } from "@goauthentik/api";
 | 
			
		||||
import { LicenseSummaryStatusEnum, SessionUser, UiThemeEnum } from "@goauthentik/api";
 | 
			
		||||
 | 
			
		||||
import "./AdminSidebar";
 | 
			
		||||
import {
 | 
			
		||||
    AdminSidebarEnterpriseEntries,
 | 
			
		||||
    AdminSidebarEntries,
 | 
			
		||||
    renderSidebarItems,
 | 
			
		||||
} from "./AdminSidebar.js";
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "development") {
 | 
			
		||||
    await import("@goauthentik/esbuild-plugin-live-reload/client");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@customElement("ak-interface-admin")
 | 
			
		||||
export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
 | 
			
		||||
    //#region Properties
 | 
			
		||||
 | 
			
		||||
    @property({ type: Boolean })
 | 
			
		||||
    notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
 | 
			
		||||
 | 
			
		||||
@ -54,12 +65,29 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
    @query("ak-about-modal")
 | 
			
		||||
    aboutModal?: AboutModal;
 | 
			
		||||
 | 
			
		||||
    @property({ type: Boolean, reflect: true })
 | 
			
		||||
    public sidebarOpen: boolean;
 | 
			
		||||
 | 
			
		||||
    #toggleSidebar = () => {
 | 
			
		||||
        this.sidebarOpen = !this.sidebarOpen;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #sidebarMatcher: MediaQueryList;
 | 
			
		||||
    #sidebarListener = (event: MediaQueryListEvent) => {
 | 
			
		||||
        this.sidebarOpen = event.matches;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //#endregion
 | 
			
		||||
 | 
			
		||||
    //#region Styles
 | 
			
		||||
 | 
			
		||||
    static get styles(): CSSResult[] {
 | 
			
		||||
        return [
 | 
			
		||||
            PFBase,
 | 
			
		||||
            PFPage,
 | 
			
		||||
            PFButton,
 | 
			
		||||
            PFDrawer,
 | 
			
		||||
            PFNav,
 | 
			
		||||
            css`
 | 
			
		||||
                .pf-c-page__main,
 | 
			
		||||
                .pf-c-drawer__content,
 | 
			
		||||
@ -67,23 +95,30 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
                    z-index: auto !important;
 | 
			
		||||
                    background-color: transparent;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                .display-none {
 | 
			
		||||
                    display: none;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                .pf-c-page {
 | 
			
		||||
                    background-color: var(--pf-c-page--BackgroundColor) !important;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                :host([theme="dark"]) {
 | 
			
		||||
                    /* Global page background colour */
 | 
			
		||||
                :host([theme="dark"]) .pf-c-page {
 | 
			
		||||
                    .pf-c-page {
 | 
			
		||||
                        --pf-c-page--BackgroundColor: var(--ak-dark-background);
 | 
			
		||||
                    }
 | 
			
		||||
                ak-enterprise-status,
 | 
			
		||||
                ak-version-banner {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ak-page-navbar {
 | 
			
		||||
                    grid-area: header;
 | 
			
		||||
                }
 | 
			
		||||
                ak-admin-sidebar {
 | 
			
		||||
 | 
			
		||||
                .ak-sidebar {
 | 
			
		||||
                    grid-area: nav;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                .pf-c-drawer__panel {
 | 
			
		||||
                    z-index: var(--pf-global--ZIndex--xl);
 | 
			
		||||
                }
 | 
			
		||||
@ -91,10 +126,23 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //#endregion
 | 
			
		||||
 | 
			
		||||
    //#region Lifecycle
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
        this.ws = new WebsocketClient();
 | 
			
		||||
 | 
			
		||||
        this.#sidebarMatcher = window.matchMedia("(min-width: 1200px)");
 | 
			
		||||
        this.sidebarOpen = this.#sidebarMatcher.matches;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public connectedCallback() {
 | 
			
		||||
        super.connectedCallback();
 | 
			
		||||
 | 
			
		||||
        window.addEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
 | 
			
		||||
 | 
			
		||||
        window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => {
 | 
			
		||||
            this.notificationDrawerOpen = !this.notificationDrawerOpen;
 | 
			
		||||
            updateURLParams({
 | 
			
		||||
@ -108,6 +156,14 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
                apiDrawerOpen: this.apiDrawerOpen,
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.#sidebarMatcher.addEventListener("change", this.#sidebarListener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public disconnectedCallback(): void {
 | 
			
		||||
        super.disconnectedCallback();
 | 
			
		||||
        window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
 | 
			
		||||
        this.#sidebarMatcher.removeEventListener("change", this.#sidebarListener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async firstUpdated(): Promise<void> {
 | 
			
		||||
@ -118,6 +174,7 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
            this.user.user.isSuperuser ||
 | 
			
		||||
            // TODO: somehow add `access_admin_interface` to the API schema
 | 
			
		||||
            this.user.user.systemPermissions.includes("access_admin_interface");
 | 
			
		||||
 | 
			
		||||
        if (!canAccessAdmin && this.user.user.pk > 0) {
 | 
			
		||||
            window.location.assign("/if/user/");
 | 
			
		||||
        }
 | 
			
		||||
@ -125,10 +182,14 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
 | 
			
		||||
    render(): TemplateResult {
 | 
			
		||||
        const sidebarClasses = {
 | 
			
		||||
            "pf-c-page__sidebar": true,
 | 
			
		||||
            "pf-m-light": this.activeTheme === UiThemeEnum.Light,
 | 
			
		||||
            "pf-m-expanded": this.sidebarOpen,
 | 
			
		||||
            "pf-m-collapsed": !this.sidebarOpen,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const drawerOpen = this.notificationDrawerOpen || this.apiDrawerOpen;
 | 
			
		||||
 | 
			
		||||
        const drawerClasses = {
 | 
			
		||||
            "pf-m-expanded": drawerOpen,
 | 
			
		||||
            "pf-m-collapsed": !drawerOpen,
 | 
			
		||||
@ -136,11 +197,18 @@ export class AdminInterface extends AuthenticatedInterface {
 | 
			
		||||
 | 
			
		||||
        return html` <ak-locale-context>
 | 
			
		||||
            <div class="pf-c-page">
 | 
			
		||||
                <ak-enterprise-status interface="admin"></ak-enterprise-status>
 | 
			
		||||
                <ak-page-navbar>
 | 
			
		||||
                    <ak-version-banner></ak-version-banner>
 | 
			
		||||
                <ak-admin-sidebar
 | 
			
		||||
                    class="pf-c-page__sidebar ${classMap(sidebarClasses)}"
 | 
			
		||||
                ></ak-admin-sidebar>
 | 
			
		||||
                    <ak-enterprise-status interface="admin"></ak-enterprise-status>
 | 
			
		||||
                </ak-page-navbar>
 | 
			
		||||
 | 
			
		||||
                <ak-sidebar class="${classMap(sidebarClasses)}">
 | 
			
		||||
                    ${renderSidebarItems(AdminSidebarEntries)}
 | 
			
		||||
                    ${this.licenseSummary?.status !== LicenseSummaryStatusEnum.Unlicensed
 | 
			
		||||
                        ? renderSidebarItems(AdminSidebarEnterpriseEntries)
 | 
			
		||||
                        : nothing}
 | 
			
		||||
                </ak-sidebar>
 | 
			
		||||
 | 
			
		||||
                <div class="pf-c-page__drawer">
 | 
			
		||||
                    <div class="pf-c-drawer ${classMap(drawerClasses)}">
 | 
			
		||||
                        <div class="pf-c-drawer__main">
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { AdminInterface } from "./AdminInterface";
 | 
			
		||||
import "./AdminInterface";
 | 
			
		||||
 | 
			
		||||
export { AdminInterface };
 | 
			
		||||
export default AdminInterface;
 | 
			
		||||
@ -94,10 +94,13 @@ export class AdminOverviewPage extends AdminOverviewBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render(): TemplateResult {
 | 
			
		||||
        const name = this.user?.user.name ?? this.user?.user.username;
 | 
			
		||||
        const username = this.user?.user.name || this.user?.user.username;
 | 
			
		||||
 | 
			
		||||
        return html`<ak-page-header description=${msg("General system status")} ?hasIcon=${false}>
 | 
			
		||||
                <span slot="header"> ${msg(str`Welcome, ${name || ""}.`)} </span>
 | 
			
		||||
        return html` <ak-page-header
 | 
			
		||||
                header=${msg(str`Welcome, ${username || ""}.`)}
 | 
			
		||||
                description=${msg("General system status")}
 | 
			
		||||
                ?hasIcon=${false}
 | 
			
		||||
            >
 | 
			
		||||
            </ak-page-header>
 | 
			
		||||
            <section class="pf-c-page__main-section">
 | 
			
		||||
                <div class="pf-l-grid pf-m-gutter">
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-number-input";
 | 
			
		||||
import "@goauthentik/components/ak-switch-input";
 | 
			
		||||
import "@goauthentik/components/ak-text-input";
 | 
			
		||||
@ -184,20 +183,14 @@ export class AdminSettingsForm extends Form<SettingsRequest> {
 | 
			
		||||
                label=${msg("Reputation: lower limit")}
 | 
			
		||||
                required
 | 
			
		||||
                name="reputationLowerLimit"
 | 
			
		||||
                value="${first(
 | 
			
		||||
                    this._settings?.reputationLowerLimit,
 | 
			
		||||
                    DEFAULT_REPUTATION_LOWER_LIMIT,
 | 
			
		||||
                )}"
 | 
			
		||||
                value="${this._settings?.reputationLowerLimit ?? DEFAULT_REPUTATION_LOWER_LIMIT}"
 | 
			
		||||
                help=${msg("Reputation cannot decrease lower than this value. Zero or negative.")}
 | 
			
		||||
            ></ak-number-input>
 | 
			
		||||
            <ak-number-input
 | 
			
		||||
                label=${msg("Reputation: upper limit")}
 | 
			
		||||
                required
 | 
			
		||||
                name="reputationUpperLimit"
 | 
			
		||||
                value="${first(
 | 
			
		||||
                    this._settings?.reputationUpperLimit,
 | 
			
		||||
                    DEFAULT_REPUTATION_UPPER_LIMIT,
 | 
			
		||||
                )}"
 | 
			
		||||
                value="${this._settings?.reputationUpperLimit ?? DEFAULT_REPUTATION_UPPER_LIMIT}"
 | 
			
		||||
                help=${msg("Reputation cannot increase higher than this value. Zero or positive.")}
 | 
			
		||||
            ></ak-number-input>
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Footer links")} name="footerLinks">
 | 
			
		||||
@ -257,7 +250,7 @@ export class AdminSettingsForm extends Form<SettingsRequest> {
 | 
			
		||||
                label=${msg("Default token length")}
 | 
			
		||||
                required
 | 
			
		||||
                name="defaultTokenLength"
 | 
			
		||||
                value="${first(this._settings?.defaultTokenLength, 60)}"
 | 
			
		||||
                value="${this._settings?.defaultTokenLength ?? 60}"
 | 
			
		||||
                help=${msg("Default length of generated tokens")}
 | 
			
		||||
            ></ak-number-input>
 | 
			
		||||
        `;
 | 
			
		||||
 | 
			
		||||
@ -83,13 +83,10 @@ export class AdminSettingsPage extends AKElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        if (!this.settings) {
 | 
			
		||||
            return nothing;
 | 
			
		||||
        }
 | 
			
		||||
        if (!this.settings) return nothing;
 | 
			
		||||
 | 
			
		||||
        return html`
 | 
			
		||||
            <ak-page-header icon="fa fa-cog" header="" description="">
 | 
			
		||||
                <span slot="header"> ${msg("System settings")} </span>
 | 
			
		||||
            </ak-page-header>
 | 
			
		||||
            <ak-page-header icon="fa fa-cog" header="${msg("System settings")}"> </ak-page-header>
 | 
			
		||||
            <section class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
 | 
			
		||||
                <div class="pf-c-card">
 | 
			
		||||
                    <div class="pf-c-card__body">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import "@goauthentik/admin/applications/ProviderSelectModal";
 | 
			
		||||
import { iconHelperText } from "@goauthentik/admin/helperText";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-file-input";
 | 
			
		||||
import "@goauthentik/components/ak-radio-input";
 | 
			
		||||
import "@goauthentik/components/ak-switch-input";
 | 
			
		||||
@ -194,7 +193,7 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
 | 
			
		||||
                    ></ak-text-input>
 | 
			
		||||
                    <ak-switch-input
 | 
			
		||||
                        name="openInNewTab"
 | 
			
		||||
                        ?checked=${first(this.instance?.openInNewTab, false)}
 | 
			
		||||
                        ?checked=${this.instance?.openInNewTab ?? false}
 | 
			
		||||
                        label=${msg("Open in new tab")}
 | 
			
		||||
                        help=${msg(
 | 
			
		||||
                            "If checked, the launch URL will open in a new browser tab or window from the user's application library.",
 | 
			
		||||
@ -221,7 +220,7 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
 | 
			
		||||
                        : html` <ak-text-input
 | 
			
		||||
                              label=${msg("Icon")}
 | 
			
		||||
                              name="metaIcon"
 | 
			
		||||
                              value=${first(this.instance?.metaIcon, "")}
 | 
			
		||||
                              value=${this.instance?.metaIcon ?? ""}
 | 
			
		||||
                              help=${iconHelperText}
 | 
			
		||||
                          >
 | 
			
		||||
                          </ak-text-input>`}
 | 
			
		||||
 | 
			
		||||
@ -113,8 +113,7 @@ export class ApplicationViewPage extends AKElement {
 | 
			
		||||
 | 
			
		||||
    renderApp(): TemplateResult {
 | 
			
		||||
        if (!this.application) {
 | 
			
		||||
            return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
 | 
			
		||||
            </ak-empty-state>`;
 | 
			
		||||
            return html`<ak-empty-state loading header=${msg("Loading")}> </ak-empty-state>`;
 | 
			
		||||
        }
 | 
			
		||||
        return html`<ak-tabs>
 | 
			
		||||
            ${this.missingOutpost
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
@ -60,7 +59,7 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
 | 
			
		||||
        return html` <ak-form-element-horizontal label=${msg("Name")} ?required=${true} name="name">
 | 
			
		||||
                <input
 | 
			
		||||
                    type="text"
 | 
			
		||||
                    value="${first(this.instance?.name, "")}"
 | 
			
		||||
                    value="${this.instance?.name ?? ""}"
 | 
			
		||||
                    class="pf-c-form-control"
 | 
			
		||||
                    required
 | 
			
		||||
                />
 | 
			
		||||
@ -72,7 +71,7 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
 | 
			
		||||
            >
 | 
			
		||||
                <ak-codemirror
 | 
			
		||||
                    mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                    value="${YAML.stringify(first(this.instance?.attributes, {}))}"
 | 
			
		||||
                    value="${YAML.stringify(this.instance?.attributes ?? {})}"
 | 
			
		||||
                >
 | 
			
		||||
                </ak-codemirror>
 | 
			
		||||
                <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import { policyOptions } from "@goauthentik/admin/applications/PolicyOptions.js";
 | 
			
		||||
import { ApplicationWizardStep } from "@goauthentik/admin/applications/wizard/ApplicationWizardStep.js";
 | 
			
		||||
import "@goauthentik/admin/applications/wizard/ak-wizard-title.js";
 | 
			
		||||
import { isSlug } from "@goauthentik/common/utils.js";
 | 
			
		||||
import { camelToSnake } from "@goauthentik/common/utils.js";
 | 
			
		||||
import "@goauthentik/components/ak-radio-input";
 | 
			
		||||
import "@goauthentik/components/ak-slug-input";
 | 
			
		||||
@ -11,6 +10,7 @@ import { type NavigableButton, type WizardButton } from "@goauthentik/components
 | 
			
		||||
import { type KeyUnknown } from "@goauthentik/elements/forms/Form";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { isSlug } from "@goauthentik/elements/router/utils.js";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
import { html } from "lit";
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { docLink } from "@goauthentik/common/global";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-toggle-group";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
@ -80,7 +79,7 @@ export class BlueprintForm extends ModelForm<BlueprintInstance, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.enabled, true)}
 | 
			
		||||
                        ?checked=${this.instance?.enabled ?? true}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -184,7 +183,7 @@ export class BlueprintForm extends ModelForm<BlueprintInstance, string> {
 | 
			
		||||
                    <ak-form-element-horizontal label=${msg("Context")} name="context">
 | 
			
		||||
                        <ak-codemirror
 | 
			
		||||
                            mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                            value="${YAML.stringify(first(this.instance?.context, {}))}"
 | 
			
		||||
                            value="${YAML.stringify(this.instance?.context ?? {})}"
 | 
			
		||||
                        >
 | 
			
		||||
                        </ak-codemirror>
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,13 @@
 | 
			
		||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
 | 
			
		||||
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import { DefaultBrand } from "@goauthentik/common/ui/config";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
 | 
			
		||||
import "@goauthentik/elements/forms/SearchSelect";
 | 
			
		||||
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
 | 
			
		||||
import YAML from "yaml";
 | 
			
		||||
 | 
			
		||||
import { msg } from "@lit/localize";
 | 
			
		||||
@ -54,7 +53,7 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
        return html` <ak-form-element-horizontal label=${msg("Domain")} required name="domain">
 | 
			
		||||
                <input
 | 
			
		||||
                    type="text"
 | 
			
		||||
                    value="${first(this.instance?.domain, window.location.host)}"
 | 
			
		||||
                    value="${this.instance?.domain ?? window.location.host}"
 | 
			
		||||
                    class="pf-c-form-control pf-m-monospace"
 | 
			
		||||
                    autocomplete="off"
 | 
			
		||||
                    spellcheck="false"
 | 
			
		||||
@ -72,7 +71,7 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?._default, false)}
 | 
			
		||||
                        ?checked=${this.instance?._default ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -92,10 +91,7 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    <ak-form-element-horizontal label=${msg("Title")} required name="brandingTitle">
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="text"
 | 
			
		||||
                            value="${first(
 | 
			
		||||
                                this.instance?.brandingTitle,
 | 
			
		||||
                                DefaultBrand.brandingTitle,
 | 
			
		||||
                            )}"
 | 
			
		||||
                            value="${this.instance?.brandingTitle ?? DefaultBrand.brandingTitle}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                            required
 | 
			
		||||
                        />
 | 
			
		||||
@ -106,7 +102,7 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    <ak-form-element-horizontal label=${msg("Logo")} required name="brandingLogo">
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="text"
 | 
			
		||||
                            value="${first(this.instance?.brandingLogo, DefaultBrand.brandingLogo)}"
 | 
			
		||||
                            value="${this.instance?.brandingLogo ?? DefaultBrand.brandingLogo}"
 | 
			
		||||
                            class="pf-c-form-control pf-m-monospace"
 | 
			
		||||
                            autocomplete="off"
 | 
			
		||||
                            spellcheck="false"
 | 
			
		||||
@ -123,10 +119,8 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="text"
 | 
			
		||||
                            value="${first(
 | 
			
		||||
                                this.instance?.brandingFavicon,
 | 
			
		||||
                                DefaultBrand.brandingFavicon,
 | 
			
		||||
                            )}"
 | 
			
		||||
                            value="${this.instance?.brandingFavicon ??
 | 
			
		||||
                            DefaultBrand.brandingFavicon}"
 | 
			
		||||
                            class="pf-c-form-control pf-m-monospace"
 | 
			
		||||
                            autocomplete="off"
 | 
			
		||||
                            spellcheck="false"
 | 
			
		||||
@ -143,10 +137,8 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="text"
 | 
			
		||||
                            value="${first(
 | 
			
		||||
                                this.instance?.brandingDefaultFlowBackground,
 | 
			
		||||
                                "/static/dist/assets/images/flow_background.jpg",
 | 
			
		||||
                            )}"
 | 
			
		||||
                            value="${this.instance?.brandingDefaultFlowBackground ??
 | 
			
		||||
                            "/static/dist/assets/images/flow_background.jpg"}"
 | 
			
		||||
                            class="pf-c-form-control pf-m-monospace"
 | 
			
		||||
                            autocomplete="off"
 | 
			
		||||
                            spellcheck="false"
 | 
			
		||||
@ -165,10 +157,8 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <ak-codemirror
 | 
			
		||||
                            mode=${CodeMirrorMode.CSS}
 | 
			
		||||
                            value="${first(
 | 
			
		||||
                                this.instance?.brandingCustomCss,
 | 
			
		||||
                                DefaultBrand.brandingCustomCss,
 | 
			
		||||
                            )}"
 | 
			
		||||
                            value="${this.instance?.brandingCustomCss ??
 | 
			
		||||
                            DefaultBrand.brandingCustomCss}"
 | 
			
		||||
                        >
 | 
			
		||||
                        </ak-codemirror>
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
@ -317,7 +307,7 @@ export class BrandForm extends ModelForm<Brand, string> {
 | 
			
		||||
                    <ak-form-element-horizontal label=${msg("Attributes")} name="attributes">
 | 
			
		||||
                        <ak-codemirror
 | 
			
		||||
                            mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                            value="${YAML.stringify(first(this.instance?.attributes, {}))}"
 | 
			
		||||
                            value="${YAML.stringify(this.instance?.attributes ?? {})}"
 | 
			
		||||
                        >
 | 
			
		||||
                        </ak-codemirror>
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
 | 
			
		||||
import "@goauthentik/elements/forms/Radio";
 | 
			
		||||
@ -185,7 +184,7 @@ export class TransportForm extends ModelForm<NotificationTransport, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.sendOnce, false)}
 | 
			
		||||
                        ?checked=${this.instance?.sendOnce ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import { DesignationToLabel, LayoutToLabel } from "@goauthentik/admin/flows/utils";
 | 
			
		||||
import { AuthenticationEnum } from "@goauthentik/api/dist/models/AuthenticationEnum";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import {
 | 
			
		||||
    CapabilitiesEnum,
 | 
			
		||||
    WithCapabilitiesConfig,
 | 
			
		||||
@ -227,7 +226,7 @@ export class FlowForm extends WithCapabilitiesConfig(ModelForm<Flow, string>) {
 | 
			
		||||
                            <input
 | 
			
		||||
                                class="pf-c-switch__input"
 | 
			
		||||
                                type="checkbox"
 | 
			
		||||
                                ?checked=${first(this.instance?.compatibilityMode, false)}
 | 
			
		||||
                                ?checked=${this.instance?.compatibilityMode ?? false}
 | 
			
		||||
                            />
 | 
			
		||||
                            <span class="pf-c-switch__toggle">
 | 
			
		||||
                                <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -407,7 +406,7 @@ export class FlowForm extends WithCapabilitiesConfig(ModelForm<Flow, string>) {
 | 
			
		||||
                          >
 | 
			
		||||
                              <input
 | 
			
		||||
                                  type="text"
 | 
			
		||||
                                  value="${first(this.instance?.background, "")}"
 | 
			
		||||
                                  value="${this.instance?.background ?? ""}"
 | 
			
		||||
                                  class="pf-c-form-control"
 | 
			
		||||
                              />
 | 
			
		||||
                              <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first, groupBy } from "@goauthentik/common/utils";
 | 
			
		||||
import { groupBy } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
 | 
			
		||||
import "@goauthentik/elements/forms/Radio";
 | 
			
		||||
@ -123,7 +123,7 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Order")} ?required=${true} name="order">
 | 
			
		||||
                <input
 | 
			
		||||
                    type="number"
 | 
			
		||||
                    value="${first(this.instance?.order, this.defaultOrder)}"
 | 
			
		||||
                    value="${this.instance?.order ?? this.defaultOrder}"
 | 
			
		||||
                    class="pf-c-form-control"
 | 
			
		||||
                    required
 | 
			
		||||
                />
 | 
			
		||||
@ -133,7 +133,7 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.evaluateOnPlan, false)}
 | 
			
		||||
                        ?checked=${this.instance?.evaluateOnPlan ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -151,7 +151,7 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.reEvaluatePolicies, true)}
 | 
			
		||||
                        ?checked=${this.instance?.reEvaluatePolicies ?? true}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import "@goauthentik/admin/groups/MemberSelectModal";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import "@goauthentik/elements/ak-dual-select/ak-dual-select-provider";
 | 
			
		||||
@ -77,7 +76,7 @@ export class GroupForm extends ModelForm<Group, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.isSuperuser, false)}
 | 
			
		||||
                        ?checked=${this.instance?.isSuperuser ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -150,7 +149,7 @@ export class GroupForm extends ModelForm<Group, string> {
 | 
			
		||||
            >
 | 
			
		||||
                <ak-codemirror
 | 
			
		||||
                    mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                    value="${YAML.stringify(first(this.instance?.attributes, {}))}"
 | 
			
		||||
                    value="${YAML.stringify(this.instance?.attributes ?? {})}"
 | 
			
		||||
                >
 | 
			
		||||
                </ak-codemirror>
 | 
			
		||||
                <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
 | 
			
		||||
import "@goauthentik/elements/forms/SearchSelect";
 | 
			
		||||
@ -53,7 +52,7 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.local, false)}
 | 
			
		||||
                        ?checked=${this.instance?.local ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
@ -57,7 +56,7 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.local, false)}
 | 
			
		||||
                        ?checked=${this.instance?.local ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -75,7 +74,7 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Kubeconfig")} name="kubeconfig">
 | 
			
		||||
                <ak-codemirror
 | 
			
		||||
                    mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                    value="${YAML.stringify(first(this.instance?.kubeconfig, {}))}"
 | 
			
		||||
                    value="${YAML.stringify(this.instance?.kubeconfig ?? {})}"
 | 
			
		||||
                >
 | 
			
		||||
                </ak-codemirror>
 | 
			
		||||
                <p class="pf-c-form__helper-text">
 | 
			
		||||
@ -87,7 +86,7 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.verifySsl, true)}
 | 
			
		||||
                        ?checked=${this.instance?.verifySsl ?? true}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import {
 | 
			
		||||
    PolicyBindingCheckTargetToLabel,
 | 
			
		||||
} from "@goauthentik/admin/policies/utils";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first, groupBy } from "@goauthentik/common/utils";
 | 
			
		||||
import { groupBy } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-toggle-group";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
 | 
			
		||||
@ -274,7 +274,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.enabled, true)}
 | 
			
		||||
                        ?checked=${this.instance?.enabled ?? true}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -289,7 +289,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.negate, false)}
 | 
			
		||||
                        ?checked=${this.instance?.negate ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -305,7 +305,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Order")} ?required=${true} name="order">
 | 
			
		||||
                <input
 | 
			
		||||
                    type="number"
 | 
			
		||||
                    value="${first(this.instance?.order, this.defaultOrder)}"
 | 
			
		||||
                    value="${this.instance?.order ?? this.defaultOrder}"
 | 
			
		||||
                    class="pf-c-form-control"
 | 
			
		||||
                    required
 | 
			
		||||
                />
 | 
			
		||||
@ -313,7 +313,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Timeout")} ?required=${true} name="timeout">
 | 
			
		||||
                <input
 | 
			
		||||
                    type="number"
 | 
			
		||||
                    value="${first(this.instance?.timeout, 30)}"
 | 
			
		||||
                    value="${this.instance?.timeout ?? 30}"
 | 
			
		||||
                    class="pf-c-form-control"
 | 
			
		||||
                    required
 | 
			
		||||
                />
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/components/ak-status-label";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
@ -125,7 +124,7 @@ export class PolicyTestForm extends Form<PolicyTestRequest> {
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Context")} name="context">
 | 
			
		||||
                <ak-codemirror
 | 
			
		||||
                    mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                    value=${YAML.stringify(first(this.request?.context, {}))}
 | 
			
		||||
                    value=${YAML.stringify(this.request?.context ?? {})}
 | 
			
		||||
                >
 | 
			
		||||
                </ak-codemirror>
 | 
			
		||||
                <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
 | 
			
		||||
@ -51,7 +50,7 @@ export class DummyPolicyForm extends BasePolicyForm<DummyPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -74,7 +73,7 @@ export class DummyPolicyForm extends BasePolicyForm<DummyPolicy> {
 | 
			
		||||
                            <input
 | 
			
		||||
                                class="pf-c-switch__input"
 | 
			
		||||
                                type="checkbox"
 | 
			
		||||
                                ?checked=${first(this.instance?.result, false)}
 | 
			
		||||
                                ?checked=${this.instance?.result ?? false}
 | 
			
		||||
                            />
 | 
			
		||||
                            <span class="pf-c-switch__toggle">
 | 
			
		||||
                                <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -91,7 +90,7 @@ export class DummyPolicyForm extends BasePolicyForm<DummyPolicy> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            value="${first(this.instance?.waitMin, 1)}"
 | 
			
		||||
                            value="${this.instance?.waitMin ?? 1}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                            required
 | 
			
		||||
                        />
 | 
			
		||||
@ -108,7 +107,7 @@ export class DummyPolicyForm extends BasePolicyForm<DummyPolicy> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            value="${first(this.instance?.waitMax, 5)}"
 | 
			
		||||
                            value="${this.instance?.waitMax ?? 5}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                            required
 | 
			
		||||
                        />
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
import "@goauthentik/elements/forms/SearchSelect";
 | 
			
		||||
@ -63,7 +62,7 @@ export class EventMatcherPolicyForm extends BasePolicyForm<EventMatcherPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
 | 
			
		||||
@ -51,7 +50,7 @@ export class PasswordExpiryPolicyForm extends BasePolicyForm<PasswordExpiryPolic
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -86,7 +85,7 @@ export class PasswordExpiryPolicyForm extends BasePolicyForm<PasswordExpiryPolic
 | 
			
		||||
                            <input
 | 
			
		||||
                                class="pf-c-switch__input"
 | 
			
		||||
                                type="checkbox"
 | 
			
		||||
                                ?checked=${first(this.instance?.denyOnly, false)}
 | 
			
		||||
                                ?checked=${this.instance?.denyOnly ?? false}
 | 
			
		||||
                            />
 | 
			
		||||
                            <span class="pf-c-switch__toggle">
 | 
			
		||||
                                <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { docLink } from "@goauthentik/common/global";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
@ -54,7 +53,7 @@ export class ExpressionPolicyForm extends BasePolicyForm<ExpressionPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/ak-dual-select";
 | 
			
		||||
import { DataProvision, DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
@ -112,7 +111,7 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            min="1"
 | 
			
		||||
                            value="${first(this.instance?.historyMaxDistanceKm, 100)}"
 | 
			
		||||
                            value="${this.instance?.historyMaxDistanceKm ?? 100}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                        />
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
@ -128,7 +127,7 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            min="1"
 | 
			
		||||
                            value="${first(this.instance?.distanceToleranceKm, 50)}"
 | 
			
		||||
                            value="${this.instance?.distanceToleranceKm ?? 50}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                        />
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
@ -142,7 +141,7 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            min="1"
 | 
			
		||||
                            value="${first(this.instance?.historyLoginCount, 5)}"
 | 
			
		||||
                            value="${this.instance?.historyLoginCount ?? 5}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                        />
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
@ -178,7 +177,7 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            min="1"
 | 
			
		||||
                            value="${first(this.instance?.impossibleToleranceKm, 50)}"
 | 
			
		||||
                            value="${this.instance?.impossibleToleranceKm ?? 50}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                        />
 | 
			
		||||
                        <p class="pf-c-form__helper-text">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
 | 
			
		||||
@ -56,7 +55,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                >
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="number"
 | 
			
		||||
                        value="${first(this.instance?.lengthMin, 10)}"
 | 
			
		||||
                        value="${this.instance?.lengthMin ?? 10}"
 | 
			
		||||
                        class="pf-c-form-control"
 | 
			
		||||
                        required
 | 
			
		||||
                    />
 | 
			
		||||
@ -68,7 +67,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                >
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="number"
 | 
			
		||||
                        value="${first(this.instance?.amountUppercase, 2)}"
 | 
			
		||||
                        value="${this.instance?.amountUppercase ?? 2}"
 | 
			
		||||
                        class="pf-c-form-control"
 | 
			
		||||
                        required
 | 
			
		||||
                    />
 | 
			
		||||
@ -80,7 +79,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                >
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="number"
 | 
			
		||||
                        value="${first(this.instance?.amountLowercase, 2)}"
 | 
			
		||||
                        value="${this.instance?.amountLowercase ?? 2}"
 | 
			
		||||
                        class="pf-c-form-control"
 | 
			
		||||
                        required
 | 
			
		||||
                    />
 | 
			
		||||
@ -92,7 +91,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                >
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="number"
 | 
			
		||||
                        value="${first(this.instance?.amountDigits, 2)}"
 | 
			
		||||
                        value="${this.instance?.amountDigits ?? 2}"
 | 
			
		||||
                        class="pf-c-form-control"
 | 
			
		||||
                        required
 | 
			
		||||
                    />
 | 
			
		||||
@ -104,7 +103,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                >
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="number"
 | 
			
		||||
                        value="${first(this.instance?.amountSymbols, 2)}"
 | 
			
		||||
                        value="${this.instance?.amountSymbols ?? 2}"
 | 
			
		||||
                        class="pf-c-form-control"
 | 
			
		||||
                        required
 | 
			
		||||
                    />
 | 
			
		||||
@ -154,7 +153,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            value="${first(this.instance?.hibpAllowedCount, 0)}"
 | 
			
		||||
                            value="${this.instance?.hibpAllowedCount ?? 0}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                            required
 | 
			
		||||
                        />
 | 
			
		||||
@ -179,7 +178,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    >
 | 
			
		||||
                        <input
 | 
			
		||||
                            type="number"
 | 
			
		||||
                            value="${first(this.instance?.zxcvbnScoreThreshold, 0)}"
 | 
			
		||||
                            value="${this.instance?.zxcvbnScoreThreshold ?? 0}"
 | 
			
		||||
                            class="pf-c-form-control"
 | 
			
		||||
                            required
 | 
			
		||||
                        />
 | 
			
		||||
@ -236,7 +235,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -272,7 +271,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.checkStaticRules, true)}
 | 
			
		||||
                        ?checked=${this.instance?.checkStaticRules ?? true}
 | 
			
		||||
                        @change=${(ev: Event) => {
 | 
			
		||||
                            const el = ev.target as HTMLInputElement;
 | 
			
		||||
                            this.showStatic = el.checked;
 | 
			
		||||
@ -291,7 +290,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.checkHaveIBeenPwned, true)}
 | 
			
		||||
                        ?checked=${this.instance?.checkHaveIBeenPwned ?? true}
 | 
			
		||||
                        @change=${(ev: Event) => {
 | 
			
		||||
                            const el = ev.target as HTMLInputElement;
 | 
			
		||||
                            this.showHIBP = el.checked;
 | 
			
		||||
@ -316,7 +315,7 @@ export class PasswordPolicyForm extends BasePolicyForm<PasswordPolicy> {
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.checkZxcvbn, true)}
 | 
			
		||||
                        ?checked=${this.instance?.checkZxcvbn ?? true}
 | 
			
		||||
                        @change=${(ev: Event) => {
 | 
			
		||||
                            const el = ev.target as HTMLInputElement;
 | 
			
		||||
                            this.showZxcvbn = el.checked;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
 | 
			
		||||
@ -61,7 +60,7 @@ doesn't pass when either or both of the selected options are equal or above the
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -84,7 +83,7 @@ doesn't pass when either or both of the selected options are equal or above the
 | 
			
		||||
                            <input
 | 
			
		||||
                                class="pf-c-switch__input"
 | 
			
		||||
                                type="checkbox"
 | 
			
		||||
                                ?checked=${first(this.instance?.checkIp, true)}
 | 
			
		||||
                                ?checked=${this.instance?.checkIp ?? true}
 | 
			
		||||
                            />
 | 
			
		||||
                            <span class="pf-c-switch__toggle">
 | 
			
		||||
                                <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -99,7 +98,7 @@ doesn't pass when either or both of the selected options are equal or above the
 | 
			
		||||
                            <input
 | 
			
		||||
                                class="pf-c-switch__input"
 | 
			
		||||
                                type="checkbox"
 | 
			
		||||
                                ?checked=${first(this.instance?.checkUsername, false)}
 | 
			
		||||
                                ?checked=${this.instance?.checkUsername ?? false}
 | 
			
		||||
                            />
 | 
			
		||||
                            <span class="pf-c-switch__toggle">
 | 
			
		||||
                                <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/forms/FormGroup";
 | 
			
		||||
import "@goauthentik/elements/forms/HorizontalFormElement";
 | 
			
		||||
 | 
			
		||||
@ -51,7 +50,7 @@ export class UniquePasswordPolicyForm extends BasePolicyForm<UniquePasswordPolic
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="pf-c-switch__input"
 | 
			
		||||
                        type="checkbox"
 | 
			
		||||
                        ?checked=${first(this.instance?.executionLogging, false)}
 | 
			
		||||
                        ?checked=${this.instance?.executionLogging ?? false}
 | 
			
		||||
                    />
 | 
			
		||||
                    <span class="pf-c-switch__toggle">
 | 
			
		||||
                        <span class="pf-c-switch__toggle-icon">
 | 
			
		||||
@ -88,7 +87,7 @@ export class UniquePasswordPolicyForm extends BasePolicyForm<UniquePasswordPolic
 | 
			
		||||
            >
 | 
			
		||||
                <input
 | 
			
		||||
                    type="number"
 | 
			
		||||
                    value="${first(this.instance?.numHistoricalPasswords, 1)}"
 | 
			
		||||
                    value="${this.instance?.numHistoricalPasswords ?? 1}"
 | 
			
		||||
                    class="pf-c-form-control"
 | 
			
		||||
                    required
 | 
			
		||||
                />
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
 | 
			
		||||
import { first } from "@goauthentik/common/utils";
 | 
			
		||||
import "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
 | 
			
		||||
import { Form } from "@goauthentik/elements/forms/Form";
 | 
			
		||||
@ -181,7 +180,7 @@ export class PolicyTestForm extends Form<PropertyMappingTestRequest> {
 | 
			
		||||
            <ak-form-element-horizontal label=${msg("Context")} name="context">
 | 
			
		||||
                <ak-codemirror
 | 
			
		||||
                    mode=${CodeMirrorMode.YAML}
 | 
			
		||||
                    value=${YAML.stringify(first(this.request?.context, {}))}
 | 
			
		||||
                    value=${YAML.stringify(this.request?.context ?? {})}
 | 
			
		||||
                >
 | 
			
		||||
                </ak-codemirror>
 | 
			
		||||
                <p class="pf-c-form__helper-text">${this.renderExampleButtons()}</p>
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user