mirror of
https://github.com/goauthentik/authentik
synced 2026-05-08 08:02:26 +02:00
Compare commits
11 Commits
flows/corr
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
001b56e2cc | ||
|
|
ecbfd2f0de | ||
|
|
45753397e1 | ||
|
|
dc6fe1dafe | ||
|
|
d5e8f2f416 | ||
|
|
d73af5a2b4 | ||
|
|
7042f2bba8 | ||
|
|
efeb260fa8 | ||
|
|
29e90092ea | ||
|
|
0abe865023 | ||
|
|
220c65a41a |
2
.github/actions/setup/action.yml
vendored
2
.github/actions/setup/action.yml
vendored
@@ -21,7 +21,7 @@ runs:
|
||||
sudo apt-get install --no-install-recommends -y libpq-dev openssl libxmlsec1-dev pkg-config gettext libkrb5-dev krb5-kdc krb5-user krb5-admin-server
|
||||
- name: Install uv
|
||||
if: ${{ contains(inputs.dependencies, 'python') }}
|
||||
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v5
|
||||
uses: astral-sh/setup-uv@ed21f2f24f8dd64503750218de024bcf64c7250a # v5
|
||||
with:
|
||||
enable-cache: true
|
||||
- name: Setup python
|
||||
|
||||
4
.github/actions/test-results/action.yml
vendored
4
.github/actions/test-results/action.yml
vendored
@@ -12,11 +12,11 @@ runs:
|
||||
with:
|
||||
flags: ${{ inputs.flags }}
|
||||
use_oidc: true
|
||||
- uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
|
||||
- uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1
|
||||
with:
|
||||
flags: ${{ inputs.flags }}
|
||||
file: unittest.xml
|
||||
use_oidc: true
|
||||
report_type: test_results
|
||||
- name: PostgreSQL Logs
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
6
.github/workflows/ci-api-docs.yml
vendored
6
.github/workflows/ci-api-docs.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
- working-directory: website/
|
||||
name: Install Dependencies
|
||||
run: npm ci
|
||||
- uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v4
|
||||
- uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 # v4
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/website/api/.docusaurus
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
env:
|
||||
NODE_ENV: production
|
||||
run: npm run build -w api
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4
|
||||
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v4
|
||||
with:
|
||||
name: api-docs
|
||||
path: website/api/build
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- build
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5
|
||||
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v5
|
||||
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5
|
||||
with:
|
||||
name: api-docs
|
||||
path: website/api/build
|
||||
|
||||
2
.github/workflows/ci-main.yml
vendored
2
.github/workflows/ci-main.yml
vendored
@@ -201,7 +201,7 @@ jobs:
|
||||
run: |
|
||||
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
|
||||
- id: cache-web
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v4
|
||||
uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 # v4
|
||||
with:
|
||||
path: web/dist
|
||||
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b
|
||||
|
||||
4
.github/workflows/release-tag.yml
vendored
4
.github/workflows/release-tag.yml
vendored
@@ -49,12 +49,8 @@ jobs:
|
||||
test:
|
||||
name: Pre-release test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- check-inputs
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5
|
||||
with:
|
||||
ref: "version-${{ needs.check-inputs.outputs.major_version }}"
|
||||
- run: make test-docker
|
||||
bump-authentik:
|
||||
name: Bump authentik version
|
||||
|
||||
@@ -26,7 +26,7 @@ RUN npm run build && \
|
||||
npm run build:sfe
|
||||
|
||||
# Stage 2: Build go proxy
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:8e8f9c84609b6005af0a4a8227cee53d6226aab1c6dcb22daf5aeeb8b05480e1 AS go-builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:5d35fb8d28b9095d123b7d96095bbf3750ff18be0a87e5a21c9cffc4351fbf96 AS go-builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@@ -76,7 +76,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
||||
/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 4: Download uv
|
||||
FROM ghcr.io/astral-sh/uv:0.9.18@sha256:5713fa8217f92b80223bc83aac7db36ec80a84437dbc0d04bbc659cae030d8c9 AS uv
|
||||
FROM ghcr.io/astral-sh/uv:0.9.17@sha256:5cb6b54d2bc3fe2eb9a8483db958a0b9eebf9edff68adedb369df8e7b98711a2 AS uv
|
||||
# Stage 5: Base python image
|
||||
FROM ghcr.io/goauthentik/fips-python:3.13.9-slim-trixie-fips@sha256:700fc8c1e290bd14e5eaca50b1d8e8c748c820010559cbfb4c4f8dfbe2c4c9ff AS python-base
|
||||
|
||||
|
||||
15
Makefile
15
Makefile
@@ -9,13 +9,6 @@ NPM_VERSION = $(shell python -m scripts.generate_semver)
|
||||
PY_SOURCES = authentik packages tests scripts lifecycle .github
|
||||
DOCKER_IMAGE ?= "authentik:test"
|
||||
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
SED_INPLACE = sed -i ''
|
||||
else
|
||||
SED_INPLACE = sed -i
|
||||
endif
|
||||
|
||||
GEN_API_TS = gen-ts-api
|
||||
GEN_API_PY = gen-py-api
|
||||
GEN_API_GO = gen-go-api
|
||||
@@ -126,8 +119,8 @@ bump: ## Bump authentik version. Usage: make bump version=20xx.xx.xx
|
||||
ifndef version
|
||||
$(error Usage: make bump version=20xx.xx.xx )
|
||||
endif
|
||||
$(SED_INPLACE) 's/^version = ".*"/version = "$(version)"/' pyproject.toml
|
||||
$(SED_INPLACE) 's/^VERSION = ".*"/VERSION = "$(version)"/' authentik/__init__.py
|
||||
sed -i 's/^version = ".*"/version = "$(version)"/' pyproject.toml
|
||||
sed -i 's/^VERSION = ".*"/VERSION = "$(version)"/' authentik/__init__.py
|
||||
$(MAKE) gen-build gen-compose aws-cfn
|
||||
npm version --no-git-tag-version --allow-same-version $(version)
|
||||
cd ${PWD}/web && npm version --no-git-tag-version --allow-same-version $(version)
|
||||
@@ -162,8 +155,8 @@ gen-diff: ## (Release) generate the changelog diff between the current schema a
|
||||
/local/schema-old.yml \
|
||||
/local/schema.yml
|
||||
rm schema-old.yml
|
||||
$(SED_INPLACE) 's/{/{/g' diff.md
|
||||
$(SED_INPLACE) 's/}/}/g' diff.md
|
||||
sed -i 's/{/{/g' diff.md
|
||||
sed -i 's/}/}/g' diff.md
|
||||
npx prettier --write diff.md
|
||||
|
||||
gen-clean-ts: ## Remove generated API client for TypeScript
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from functools import lru_cache
|
||||
from os import environ
|
||||
|
||||
VERSION = "2026.2.0-rc1"
|
||||
VERSION = "2025.12.0-rc1"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class VersionSerializer(PassiveSerializer):
|
||||
|
||||
def get_version_latest(self, _) -> str:
|
||||
"""Get latest version from cache"""
|
||||
if get_current_tenant().schema_name != get_public_schema_name():
|
||||
if get_current_tenant().schema_name == get_public_schema_name():
|
||||
return authentik_version()
|
||||
version_in_cache = cache.get(VERSION_CACHE_KEY)
|
||||
if not version_in_cache: # pragma: no cover
|
||||
|
||||
@@ -15,9 +15,7 @@ class Pagination(pagination.PageNumberPagination):
|
||||
|
||||
def get_page_size(self, request):
|
||||
if self.page_size_query_param in request.query_params:
|
||||
page_size = super().get_page_size(request)
|
||||
if page_size is not None:
|
||||
return min(super().get_page_size(request), request.tenant.pagination_max_page_size)
|
||||
return min(super().get_page_size(request), request.tenant.pagination_max_page_size)
|
||||
return request.tenant.pagination_default_page_size
|
||||
|
||||
def get_paginated_response(self, data):
|
||||
|
||||
@@ -33,16 +33,6 @@ from authentik.endpoints.connectors.agent.auth import AgentAuth
|
||||
from authentik.rbac.api.roles import RoleSerializer
|
||||
from authentik.rbac.decorators import permission_required
|
||||
|
||||
PARTIAL_USER_SERIALIZER_MODEL_FIELDS = [
|
||||
"pk",
|
||||
"username",
|
||||
"name",
|
||||
"is_active",
|
||||
"last_login",
|
||||
"email",
|
||||
"attributes",
|
||||
]
|
||||
|
||||
|
||||
class PartialUserSerializer(ModelSerializer):
|
||||
"""Partial User Serializer, does not include child relations."""
|
||||
@@ -52,7 +42,16 @@ class PartialUserSerializer(ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = PARTIAL_USER_SERIALIZER_MODEL_FIELDS + ["uid"]
|
||||
fields = [
|
||||
"pk",
|
||||
"username",
|
||||
"name",
|
||||
"is_active",
|
||||
"last_login",
|
||||
"email",
|
||||
"attributes",
|
||||
"uid",
|
||||
]
|
||||
|
||||
|
||||
class RelatedGroupSerializer(ModelSerializer):
|
||||
@@ -263,14 +262,7 @@ class GroupViewSet(UsedByMixin, ModelViewSet):
|
||||
base_qs = Group.objects.all().prefetch_related("roles")
|
||||
|
||||
if self.serializer_class(context={"request": self.request})._should_include_users:
|
||||
# Only fetch fields needed by PartialUserSerializer to reduce DB load and instantiation
|
||||
# time
|
||||
base_qs = base_qs.prefetch_related(
|
||||
Prefetch(
|
||||
"users",
|
||||
queryset=User.objects.all().only(*PARTIAL_USER_SERIALIZER_MODEL_FIELDS),
|
||||
)
|
||||
)
|
||||
base_qs = base_qs.prefetch_related("users")
|
||||
else:
|
||||
base_qs = base_qs.prefetch_related(
|
||||
Prefetch("users", queryset=User.objects.all().only("id"))
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Any
|
||||
|
||||
from django.utils.timezone import now
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import CharField
|
||||
@@ -144,6 +145,12 @@ class TokenViewSet(UsedByMixin, ModelViewSet):
|
||||
owner_field = "user"
|
||||
rbac_allow_create_without_perm = True
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
if user.is_superuser:
|
||||
return super().get_queryset()
|
||||
return super().get_queryset().filter(user=user.pk)
|
||||
|
||||
def perform_create(self, serializer: TokenSerializer):
|
||||
if not self.request.user.is_superuser:
|
||||
instance = serializer.save(
|
||||
|
||||
@@ -18,9 +18,10 @@ def migrate_object_permissions(apps: Apps, schema_editor: BaseDatabaseSchemaEdit
|
||||
RoleModelPermission = apps.get_model("guardian", "RoleModelPermission")
|
||||
|
||||
def get_role_for_user_id(user_id: int) -> Role:
|
||||
name = f"ak-migrated-role--user-{user_id}"
|
||||
name = f"ak-managed-role--user-{user_id}"
|
||||
role, created = Role.objects.using(db_alias).get_or_create(
|
||||
name=name,
|
||||
managed=name,
|
||||
)
|
||||
if created:
|
||||
role.users.add(user_id)
|
||||
@@ -31,10 +32,11 @@ def migrate_object_permissions(apps: Apps, schema_editor: BaseDatabaseSchemaEdit
|
||||
if not role:
|
||||
# Every django group should already have a role, so this should never happen.
|
||||
# But let's be nice.
|
||||
name = f"ak-migrated-role--group-{group_id}"
|
||||
name = f"ak-managed-role--group-{group_id}"
|
||||
role, created = Role.objects.using(db_alias).get_or_create(
|
||||
group_id=group_id,
|
||||
name=name,
|
||||
managed=name,
|
||||
)
|
||||
if created:
|
||||
role.group_id = group_id
|
||||
|
||||
@@ -183,16 +183,16 @@ class TestTokenAPI(APITestCase):
|
||||
self.assertEqual(len(body["results"]), 1)
|
||||
self.assertEqual(body["results"][0]["identifier"], token_should.identifier)
|
||||
|
||||
def test_list_with_permission(self):
|
||||
"""Test Token List (Test with `view_token` permission)"""
|
||||
def test_list_admin(self):
|
||||
"""Test Token List (Test with admin auth)"""
|
||||
Token.objects.all().delete()
|
||||
self.client.force_login(self.admin)
|
||||
token_should: Token = Token.objects.create(
|
||||
identifier="test", expiring=False, user=self.user
|
||||
)
|
||||
token_should_not: Token = Token.objects.create(
|
||||
identifier="test-2", expiring=False, user=get_anonymous_user()
|
||||
)
|
||||
self.user.assign_perms_to_managed_role("authentik_core.view_token")
|
||||
response = self.client.get(reverse("authentik_api:token-list"))
|
||||
body = loads(response.content)
|
||||
self.assertEqual(len(body["results"]), 2)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Crypto API Views"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||
from cryptography.x509 import load_pem_x509_certificate
|
||||
@@ -13,12 +15,14 @@ from drf_spectacular.utils import (
|
||||
OpenApiParameter,
|
||||
OpenApiResponse,
|
||||
extend_schema,
|
||||
extend_schema_field,
|
||||
)
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import (
|
||||
CharField,
|
||||
ChoiceField,
|
||||
DateTimeField,
|
||||
IntegerField,
|
||||
SerializerMethodField,
|
||||
)
|
||||
@@ -47,15 +51,59 @@ LOGGER = get_logger()
|
||||
class CertificateKeyPairSerializer(ModelSerializer):
|
||||
"""CertificateKeyPair Serializer"""
|
||||
|
||||
fingerprint_sha256 = SerializerMethodField()
|
||||
fingerprint_sha1 = SerializerMethodField()
|
||||
|
||||
cert_expiry = SerializerMethodField()
|
||||
cert_subject = SerializerMethodField()
|
||||
private_key_available = SerializerMethodField()
|
||||
key_type = SerializerMethodField()
|
||||
|
||||
certificate_download_url = SerializerMethodField()
|
||||
private_key_download_url = SerializerMethodField()
|
||||
|
||||
@property
|
||||
def _should_include_details(self) -> bool:
|
||||
request: Request = self.context.get("request", None)
|
||||
if not request:
|
||||
return True
|
||||
return str(request.query_params.get("include_details", "true")).lower() == "true"
|
||||
|
||||
def get_fingerprint_sha256(self, instance: CertificateKeyPair) -> str | None:
|
||||
"Get certificate Hash (SHA256)"
|
||||
if not self._should_include_details:
|
||||
return None
|
||||
return instance.fingerprint_sha256
|
||||
|
||||
def get_fingerprint_sha1(self, instance: CertificateKeyPair) -> str | None:
|
||||
"Get certificate Hash (SHA1)"
|
||||
if not self._should_include_details:
|
||||
return None
|
||||
return instance.fingerprint_sha1
|
||||
|
||||
def get_cert_expiry(self, instance: CertificateKeyPair) -> datetime | None:
|
||||
"Get certificate expiry"
|
||||
if not self._should_include_details:
|
||||
return None
|
||||
return DateTimeField().to_representation(instance.certificate.not_valid_after_utc)
|
||||
|
||||
def get_cert_subject(self, instance: CertificateKeyPair) -> str | None:
|
||||
"""Get certificate subject as full rfc4514"""
|
||||
if not self._should_include_details:
|
||||
return None
|
||||
return instance.certificate.subject.rfc4514_string()
|
||||
|
||||
def get_private_key_available(self, instance: CertificateKeyPair) -> bool:
|
||||
"""Show if this keypair has a private key configured or not"""
|
||||
return instance.key_data != "" and instance.key_data is not None
|
||||
|
||||
@extend_schema_field(ChoiceField(choices=KeyType.choices, allow_null=True))
|
||||
def get_key_type(self, instance: CertificateKeyPair) -> str | None:
|
||||
"""Get the key algorithm type from the certificate's public key"""
|
||||
if not self._should_include_details:
|
||||
return None
|
||||
return instance.key_type
|
||||
|
||||
def get_certificate_download_url(self, instance: CertificateKeyPair) -> str:
|
||||
"""Get URL to download certificate"""
|
||||
return (
|
||||
@@ -127,11 +175,6 @@ class CertificateKeyPairSerializer(ModelSerializer):
|
||||
"managed": {"read_only": True},
|
||||
"key_data": {"write_only": True},
|
||||
"certificate_data": {"write_only": True},
|
||||
"fingerprint_sha256": {"read_only": True},
|
||||
"fingerprint_sha1": {"read_only": True},
|
||||
"cert_expiry": {"read_only": True},
|
||||
"cert_subject": {"read_only": True},
|
||||
"key_type": {"read_only": True},
|
||||
}
|
||||
|
||||
|
||||
@@ -173,12 +216,17 @@ class CertificateKeyPairFilter(FilterSet):
|
||||
return queryset.exclude(key_data__exact="")
|
||||
|
||||
def filter_key_type(self, queryset, name, value): # pragma: no cover
|
||||
"""Filter certificates by key type using the stored database field"""
|
||||
"""Filter certificates by key type using the public key from the certificate"""
|
||||
if not value:
|
||||
return queryset
|
||||
|
||||
# value is a list of KeyType enum values from MultipleChoiceFilter
|
||||
return queryset.filter(key_type__in=value)
|
||||
filtered_pks = []
|
||||
for cert in queryset:
|
||||
if cert.key_type in value:
|
||||
filtered_pks.append(cert.pk)
|
||||
|
||||
return queryset.filter(pk__in=filtered_pks)
|
||||
|
||||
class Meta:
|
||||
model = CertificateKeyPair
|
||||
@@ -215,6 +263,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
|
||||
"Can be specified multiple times (e.g. '?key_type=rsa&key_type=ec')"
|
||||
),
|
||||
),
|
||||
OpenApiParameter("include_details", bool, default=True),
|
||||
]
|
||||
)
|
||||
def list(self, request, *args, **kwargs):
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
# Generated by Django 5.2.9 on 2025-12-09 06:22
|
||||
|
||||
from hashlib import md5
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.x509 import load_pem_x509_certificate
|
||||
from django.db import migrations, models
|
||||
|
||||
from authentik.crypto.signals import extract_certificate_metadata
|
||||
|
||||
|
||||
def backfill_certificate_metadata(apps, schema_editor): # noqa: ARG001
|
||||
"""Backfill certificate metadata and kid for existing records."""
|
||||
|
||||
CertificateKeyPair = apps.get_model("authentik_crypto", "CertificateKeyPair")
|
||||
|
||||
for cert in CertificateKeyPair.objects.all():
|
||||
updated_fields = []
|
||||
|
||||
if cert.certificate_data:
|
||||
try:
|
||||
certificate = load_pem_x509_certificate(
|
||||
cert.certificate_data.encode("utf-8"), default_backend()
|
||||
)
|
||||
metadata = extract_certificate_metadata(certificate)
|
||||
|
||||
cert.key_type = metadata["key_type"]
|
||||
cert.cert_expiry = metadata["cert_expiry"]
|
||||
cert.cert_subject = metadata["cert_subject"]
|
||||
cert.fingerprint_sha256 = metadata["fingerprint_sha256"]
|
||||
cert.fingerprint_sha1 = metadata["fingerprint_sha1"]
|
||||
updated_fields.extend(
|
||||
[
|
||||
"key_type",
|
||||
"cert_expiry",
|
||||
"cert_subject",
|
||||
"fingerprint_sha256",
|
||||
"fingerprint_sha1",
|
||||
]
|
||||
)
|
||||
except (ValueError, TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
# Backfill kid with MD5 for backwards compatibility
|
||||
if cert.key_data:
|
||||
cert.kid = md5(cert.key_data.encode("utf-8"), usedforsecurity=False).hexdigest()
|
||||
updated_fields.append("kid")
|
||||
|
||||
if updated_fields:
|
||||
cert.save(update_fields=updated_fields)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_crypto", "0005_alter_certificatekeypair_options"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="cert_expiry",
|
||||
field=models.DateTimeField(blank=True, help_text="Certificate expiry date", null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="cert_subject",
|
||||
field=models.TextField(
|
||||
blank=True, help_text="Certificate subject as RFC4514 string", null=True
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="fingerprint_sha1",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
help_text="SHA1 fingerprint of the certificate",
|
||||
max_length=59,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="fingerprint_sha256",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
help_text="SHA256 fingerprint of the certificate",
|
||||
max_length=95,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="key_type",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("rsa", "RSA"),
|
||||
("ec", "Elliptic Curve"),
|
||||
("dsa", "DSA"),
|
||||
("ed25519", "Ed25519"),
|
||||
("ed448", "Ed448"),
|
||||
],
|
||||
help_text="Key algorithm type detected from the certificate's public key",
|
||||
max_length=16,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="certificatekeypair",
|
||||
name="kid",
|
||||
field=models.CharField(
|
||||
blank=True, help_text="Key ID generated from private key", max_length=128, null=True
|
||||
),
|
||||
),
|
||||
migrations.RunPython(backfill_certificate_metadata, migrations.RunPython.noop),
|
||||
]
|
||||
@@ -1,8 +1,7 @@
|
||||
"""authentik crypto models"""
|
||||
|
||||
from base64 import urlsafe_b64encode
|
||||
from binascii import hexlify
|
||||
from hashlib import md5, sha512
|
||||
from hashlib import md5
|
||||
from ssl import PEM_FOOTER, PEM_HEADER
|
||||
from textwrap import wrap
|
||||
from uuid import uuid4
|
||||
@@ -48,39 +47,6 @@ def fingerprint_sha256(cert: Certificate) -> str:
|
||||
return hexlify(cert.fingerprint(hashes.SHA256()), ":").decode("utf-8")
|
||||
|
||||
|
||||
def detect_key_type(certificate: Certificate) -> str | None:
|
||||
"""Detect the key algorithm type by parsing the certificate's public key"""
|
||||
try:
|
||||
public_key = certificate.public_key()
|
||||
if isinstance(public_key, RSAPublicKey):
|
||||
return KeyType.RSA
|
||||
if isinstance(public_key, EllipticCurvePublicKey):
|
||||
return KeyType.EC
|
||||
if isinstance(public_key, DSAPublicKey):
|
||||
return KeyType.DSA
|
||||
if isinstance(public_key, Ed25519PublicKey):
|
||||
return KeyType.ED25519
|
||||
if isinstance(public_key, Ed448PublicKey):
|
||||
return KeyType.ED448
|
||||
except (ValueError, TypeError, AttributeError) as exc:
|
||||
LOGGER.warning("Failed to detect key type", exc=exc)
|
||||
return None
|
||||
|
||||
|
||||
def generate_key_id(key_data: str) -> str:
|
||||
"""Generate Key ID using SHA512 + urlsafe_b64encode."""
|
||||
if not key_data:
|
||||
return ""
|
||||
return urlsafe_b64encode(sha512(key_data.encode("utf-8")).digest()).decode("utf-8").rstrip("=")
|
||||
|
||||
|
||||
def generate_key_id_legacy(key_data: str) -> str:
|
||||
"""Generate Key ID using MD5 (legacy format for backwards compatibility)."""
|
||||
if not key_data:
|
||||
return ""
|
||||
return md5(key_data.encode("utf-8")).hexdigest() # nosec
|
||||
|
||||
|
||||
class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
"""CertificateKeyPair that can be used for signing or encrypting if `key_data`
|
||||
is set, otherwise it can be used to verify remote data."""
|
||||
@@ -96,41 +62,6 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
blank=True,
|
||||
default="",
|
||||
)
|
||||
key_type = models.CharField(
|
||||
max_length=16,
|
||||
choices=KeyType.choices,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("Key algorithm type detected from the certificate's public key"),
|
||||
)
|
||||
cert_expiry = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("Certificate expiry date"),
|
||||
)
|
||||
cert_subject = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("Certificate subject as RFC4514 string"),
|
||||
)
|
||||
fingerprint_sha256 = models.CharField(
|
||||
max_length=95,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("SHA256 fingerprint of the certificate"),
|
||||
)
|
||||
fingerprint_sha1 = models.CharField(
|
||||
max_length=59,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("SHA1 fingerprint of the certificate"),
|
||||
)
|
||||
kid = models.CharField(
|
||||
max_length=128,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_("Key ID generated from private key"),
|
||||
)
|
||||
|
||||
_cert: Certificate | None = None
|
||||
_private_key: PrivateKeyTypes | None = None
|
||||
@@ -175,6 +106,41 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
return None
|
||||
return self._private_key
|
||||
|
||||
@property
|
||||
def fingerprint_sha256(self) -> str:
|
||||
"""Get SHA256 Fingerprint of certificate_data"""
|
||||
return fingerprint_sha256(self.certificate)
|
||||
|
||||
@property
|
||||
def fingerprint_sha1(self) -> str:
|
||||
"""Get SHA1 Fingerprint of certificate_data"""
|
||||
return hexlify(self.certificate.fingerprint(hashes.SHA1()), ":").decode("utf-8") # nosec
|
||||
|
||||
@property
|
||||
def kid(self):
|
||||
"""Get Key ID used for JWKS"""
|
||||
return (
|
||||
md5(self.key_data.encode("utf-8"), usedforsecurity=False).hexdigest()
|
||||
if self.key_data
|
||||
else ""
|
||||
) # nosec
|
||||
|
||||
@property
|
||||
def key_type(self) -> str | None:
|
||||
"""Get the key algorithm type from the certificate's public key"""
|
||||
public_key = self.certificate.public_key()
|
||||
if isinstance(public_key, RSAPublicKey):
|
||||
return KeyType.RSA
|
||||
if isinstance(public_key, EllipticCurvePublicKey):
|
||||
return KeyType.EC
|
||||
if isinstance(public_key, DSAPublicKey):
|
||||
return KeyType.DSA
|
||||
if isinstance(public_key, Ed25519PublicKey):
|
||||
return KeyType.ED25519
|
||||
if isinstance(public_key, Ed448PublicKey):
|
||||
return KeyType.ED448
|
||||
return None
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Certificate-Key Pair {self.name}"
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
"""authentik crypto signals"""
|
||||
|
||||
from binascii import hexlify
|
||||
from datetime import datetime
|
||||
from ssl import CertificateError
|
||||
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.x509 import Certificate
|
||||
from django.db.models.signals import pre_save
|
||||
from django.dispatch import receiver
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.crypto.models import (
|
||||
CertificateKeyPair,
|
||||
detect_key_type,
|
||||
fingerprint_sha256,
|
||||
generate_key_id,
|
||||
generate_key_id_legacy,
|
||||
)
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
def extract_certificate_metadata(certificate: Certificate) -> dict[str, str | datetime]:
|
||||
"""Extract all metadata fields from a certificate."""
|
||||
metadata = {}
|
||||
|
||||
try:
|
||||
metadata["key_type"] = detect_key_type(certificate)
|
||||
metadata["cert_expiry"] = certificate.not_valid_after_utc
|
||||
metadata["cert_subject"] = certificate.subject.rfc4514_string()
|
||||
metadata["fingerprint_sha256"] = fingerprint_sha256(certificate)
|
||||
metadata["fingerprint_sha1"] = hexlify(
|
||||
certificate.fingerprint(hashes.SHA1()), ":" # nosec
|
||||
).decode("utf-8")
|
||||
except (ValueError, TypeError, AttributeError) as exc:
|
||||
raise CertificateError(f"Invalid certificate metadata: {exc}") from exc
|
||||
|
||||
return metadata
|
||||
|
||||
|
||||
@receiver(pre_save, sender="authentik_crypto.CertificateKeyPair")
|
||||
def certificate_key_pair_pre_save(
|
||||
sender: type[CertificateKeyPair], instance: CertificateKeyPair, **_
|
||||
):
|
||||
"""Automatically populate certificate metadata fields before saving"""
|
||||
|
||||
# Only extract metadata if certificate_data is present
|
||||
if not instance.certificate_data:
|
||||
return
|
||||
|
||||
try:
|
||||
metadata = extract_certificate_metadata(instance.certificate)
|
||||
except (CertificateError, ValueError, TypeError, AttributeError) as exc:
|
||||
LOGGER.warning("Failed to extract certificate metadata", exc=exc)
|
||||
return
|
||||
|
||||
instance.key_type = metadata["key_type"]
|
||||
instance.cert_expiry = metadata["cert_expiry"]
|
||||
instance.cert_subject = metadata["cert_subject"]
|
||||
instance.fingerprint_sha256 = metadata["fingerprint_sha256"]
|
||||
instance.fingerprint_sha1 = metadata["fingerprint_sha1"]
|
||||
|
||||
# Generate kid if not set, or regenerate if key_data has changed
|
||||
# Preserve existing kid (MD5 or SHA512) if it matches the current key_data
|
||||
if instance.key_data:
|
||||
new_kid = generate_key_id(instance.key_data)
|
||||
legacy_kid = generate_key_id_legacy(instance.key_data)
|
||||
if instance.kid not in (new_kid, legacy_kid):
|
||||
instance.kid = new_kid
|
||||
@@ -20,7 +20,7 @@ from authentik.core.tests.utils import (
|
||||
)
|
||||
from authentik.crypto.api import CertificateKeyPairSerializer
|
||||
from authentik.crypto.builder import CertificateBuilder
|
||||
from authentik.crypto.models import CertificateKeyPair, generate_key_id, generate_key_id_legacy
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.crypto.tasks import MANAGED_DISCOVERED, certificate_discovery
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_id, generate_key
|
||||
@@ -173,24 +173,21 @@ class TestCrypto(APITestCase):
|
||||
self.assertEqual(api_cert["fingerprint_sha1"], cert.fingerprint_sha1)
|
||||
self.assertEqual(api_cert["fingerprint_sha256"], cert.fingerprint_sha256)
|
||||
|
||||
def test_list_always_includes_details(self):
|
||||
"""Test API List always includes certificate details"""
|
||||
def test_list_without_details(self):
|
||||
"""Test API List (no details)"""
|
||||
cert = create_test_cert()
|
||||
self.client.force_login(create_test_admin_user())
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"authentik_api:certificatekeypair-list",
|
||||
),
|
||||
data={"name": cert.name},
|
||||
data={"name": cert.name, "include_details": False},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
body = loads(response.content.decode())
|
||||
api_cert = [x for x in body["results"] if x["name"] == cert.name][0]
|
||||
# All details should now always be included
|
||||
self.assertEqual(api_cert["fingerprint_sha1"], cert.fingerprint_sha1)
|
||||
self.assertEqual(api_cert["fingerprint_sha256"], cert.fingerprint_sha256)
|
||||
self.assertIsNotNone(api_cert["cert_expiry"])
|
||||
self.assertIsNotNone(api_cert["cert_subject"])
|
||||
self.assertEqual(api_cert["fingerprint_sha1"], None)
|
||||
self.assertEqual(api_cert["fingerprint_sha256"], None)
|
||||
|
||||
def test_certificate_download(self):
|
||||
"""Test certificate export (download)"""
|
||||
@@ -429,114 +426,3 @@ class TestCrypto(APITestCase):
|
||||
self.assertEqual(
|
||||
1, final_count, "Should not create duplicate cert for same private key"
|
||||
)
|
||||
|
||||
def test_metadata_extraction_with_cert_and_key(self):
|
||||
"""Test that metadata is extracted when creating keypair with certificate and key"""
|
||||
cert = create_test_cert()
|
||||
|
||||
# Verify all metadata fields are populated
|
||||
self.assertIsNotNone(cert.key_type)
|
||||
self.assertIsNotNone(cert.cert_expiry)
|
||||
self.assertIsNotNone(cert.cert_subject)
|
||||
self.assertIsNotNone(cert.fingerprint_sha256)
|
||||
self.assertIsNotNone(cert.fingerprint_sha1)
|
||||
|
||||
# Verify kid is generated using SHA512 for new records
|
||||
self.assertIsNotNone(cert.kid)
|
||||
self.assertEqual(cert.kid, generate_key_id(cert.key_data))
|
||||
|
||||
def test_metadata_extraction_without_key(self):
|
||||
"""Test that metadata is extracted when creating keypair without private key"""
|
||||
builder = CertificateBuilder(generate_id())
|
||||
builder.build(subject_alt_names=[], validity_days=3)
|
||||
|
||||
# Create keypair with only certificate, no key
|
||||
cert = CertificateKeyPair.objects.create(
|
||||
name=generate_id(),
|
||||
certificate_data=builder.certificate,
|
||||
key_data="",
|
||||
)
|
||||
|
||||
# Verify certificate metadata fields are populated
|
||||
self.assertIsNotNone(cert.key_type)
|
||||
self.assertIsNotNone(cert.cert_expiry)
|
||||
self.assertIsNotNone(cert.cert_subject)
|
||||
self.assertIsNotNone(cert.fingerprint_sha256)
|
||||
self.assertIsNotNone(cert.fingerprint_sha1)
|
||||
|
||||
# Verify kid is empty when no key_data
|
||||
self.assertEqual(cert.kid, None)
|
||||
|
||||
def test_metadata_extraction_invalid_cert(self):
|
||||
"""Test that invalid certificate data doesn't crash, just skips metadata"""
|
||||
cert = CertificateKeyPair.objects.create(
|
||||
name=generate_id(),
|
||||
certificate_data="invalid certificate data",
|
||||
key_data="",
|
||||
)
|
||||
|
||||
# Verify metadata fields are None for invalid cert
|
||||
self.assertIsNone(cert.key_type)
|
||||
self.assertIsNone(cert.cert_expiry)
|
||||
self.assertIsNone(cert.cert_subject)
|
||||
self.assertIsNone(cert.fingerprint_sha256)
|
||||
self.assertIsNone(cert.fingerprint_sha1)
|
||||
self.assertIsNone(cert.kid)
|
||||
|
||||
def test_kid_legacy_preservation(self):
|
||||
"""Test that legacy MD5 kid is preserved when key_data hasn't changed"""
|
||||
cert = create_test_cert()
|
||||
|
||||
# Simulate a legacy MD5 kid (as if backfilled from old system)
|
||||
legacy_kid = generate_key_id_legacy(cert.key_data)
|
||||
CertificateKeyPair.objects.filter(pk=cert.pk).update(kid=legacy_kid)
|
||||
cert.refresh_from_db()
|
||||
self.assertEqual(cert.kid, legacy_kid)
|
||||
|
||||
# Save the cert again (e.g., name change) - kid should be preserved
|
||||
cert.name = generate_id()
|
||||
cert.save()
|
||||
cert.refresh_from_db()
|
||||
|
||||
self.assertEqual(cert.kid, legacy_kid)
|
||||
|
||||
def test_kid_regenerated_on_key_change(self):
|
||||
"""Test that kid is regenerated when key_data changes"""
|
||||
cert = create_test_cert()
|
||||
original_kid = cert.kid
|
||||
|
||||
# Generate a new key and update the keypair
|
||||
builder = CertificateBuilder(generate_id())
|
||||
builder.build(subject_alt_names=[], validity_days=3)
|
||||
|
||||
cert.key_data = builder.private_key
|
||||
cert.certificate_data = builder.certificate
|
||||
cert.save()
|
||||
cert.refresh_from_db()
|
||||
|
||||
# Kid should be regenerated for the new key
|
||||
self.assertNotEqual(cert.kid, original_kid)
|
||||
self.assertEqual(cert.kid, generate_key_id(cert.key_data))
|
||||
|
||||
def test_kid_regenerated_on_key_change_from_legacy(self):
|
||||
"""Test that kid is regenerated from legacy MD5 when key_data changes"""
|
||||
cert = create_test_cert()
|
||||
|
||||
# Simulate a legacy MD5 kid
|
||||
legacy_kid = generate_key_id_legacy(cert.key_data)
|
||||
CertificateKeyPair.objects.filter(pk=cert.pk).update(kid=legacy_kid)
|
||||
cert.refresh_from_db()
|
||||
self.assertEqual(cert.kid, legacy_kid)
|
||||
|
||||
# Generate a new key and update the keypair
|
||||
builder = CertificateBuilder(generate_id())
|
||||
builder.build(subject_alt_names=[], validity_days=3)
|
||||
|
||||
cert.key_data = builder.private_key
|
||||
cert.certificate_data = builder.certificate
|
||||
cert.save()
|
||||
cert.refresh_from_db()
|
||||
|
||||
# Kid should now be SHA512 for the new key
|
||||
self.assertNotEqual(cert.kid, legacy_kid)
|
||||
self.assertEqual(cert.kid, generate_key_id(cert.key_data))
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
from typing import cast
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from rest_framework.authentication import BaseAuthentication
|
||||
from rest_framework.request import Request
|
||||
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
|
||||
|
||||
class FlowActive(BaseAuthentication):
|
||||
"""Authenticate requests when a flow is currently active"""
|
||||
|
||||
def authenticate(self, request: Request):
|
||||
plan = cast(FlowPlan | None, request.session.get(SESSION_KEY_PLAN))
|
||||
if not plan:
|
||||
return None
|
||||
return (plan.context.get(PLAN_CONTEXT_PENDING_USER, AnonymousUser()), plan)
|
||||
@@ -249,7 +249,7 @@ class ChallengeStageView(StageView):
|
||||
"f(ch): invalid challenge response",
|
||||
errors=challenge_response.errors,
|
||||
)
|
||||
return HttpChallengeResponse(challenge_response, status=400)
|
||||
return HttpChallengeResponse(challenge_response)
|
||||
|
||||
|
||||
class AccessDeniedStage(ChallengeStageView):
|
||||
|
||||
@@ -48,9 +48,6 @@ class FlowTestCase(APITestCase):
|
||||
self.assertEqual(raw_response[key], expected)
|
||||
return raw_response
|
||||
|
||||
def get_flow_plan(self) -> FlowPlan | None:
|
||||
return self.client.session.get(SESSION_KEY_PLAN)
|
||||
|
||||
def assertStageRedirects(self, response: HttpResponse, to: str) -> dict[str, Any]:
|
||||
"""Wrapper around assertStageResponse that checks for a redirect"""
|
||||
return self.assertStageResponse(response, component="xak-flow-redirect", to=to)
|
||||
|
||||
@@ -147,8 +147,6 @@ class FlowExecutorView(APIView):
|
||||
token.delete()
|
||||
if not isinstance(plan, FlowPlan):
|
||||
return None
|
||||
if existing_plan := self.request.session[SESSION_KEY_PLAN]:
|
||||
plan.context.update(existing_plan.context)
|
||||
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||
self._logger.debug("f(exec): restored flow plan from token", plan=plan)
|
||||
return plan
|
||||
@@ -258,11 +256,6 @@ class FlowExecutorView(APIView):
|
||||
serializers=challenge_types,
|
||||
resource_type_field_name="component",
|
||||
),
|
||||
400: PolymorphicProxySerializer(
|
||||
component_name="ChallengeTypes",
|
||||
serializers=challenge_types,
|
||||
resource_type_field_name="component",
|
||||
),
|
||||
},
|
||||
request=OpenApiTypes.NONE,
|
||||
parameters=[
|
||||
@@ -310,11 +303,6 @@ class FlowExecutorView(APIView):
|
||||
serializers=challenge_types,
|
||||
resource_type_field_name="component",
|
||||
),
|
||||
400: PolymorphicProxySerializer(
|
||||
component_name="ChallengeTypes",
|
||||
serializers=challenge_types,
|
||||
resource_type_field_name="component",
|
||||
),
|
||||
},
|
||||
request=PolymorphicProxySerializer(
|
||||
component_name="FlowChallengeResponse",
|
||||
|
||||
@@ -86,7 +86,7 @@ class OutpostConfig:
|
||||
class OutpostModel(Model):
|
||||
"""Base model for providers that need more objects than just themselves"""
|
||||
|
||||
def get_required_objects(self) -> Iterable[models.Model | str | tuple[str, models.Model]]:
|
||||
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||
"""Return a list of all required objects"""
|
||||
return [self]
|
||||
|
||||
@@ -332,35 +332,41 @@ class Outpost(ScheduledModel, SerializerModel, ManagedModel):
|
||||
"""Create per-object and global permissions for outpost service-account"""
|
||||
# To ensure the user only has the correct permissions, we delete all of them and re-add
|
||||
# the ones the user needs
|
||||
try:
|
||||
with transaction.atomic():
|
||||
user.remove_all_perms_from_managed_role()
|
||||
for model_or_perm in self.get_required_objects():
|
||||
if isinstance(model_or_perm, models.Model):
|
||||
code_name = (
|
||||
f"{model_or_perm._meta.app_label}.view_{model_or_perm._meta.model_name}"
|
||||
)
|
||||
with transaction.atomic():
|
||||
user.remove_all_perms_from_managed_role()
|
||||
for model_or_perm in self.get_required_objects():
|
||||
if isinstance(model_or_perm, models.Model):
|
||||
model_or_perm: models.Model
|
||||
code_name = (
|
||||
f"{model_or_perm._meta.app_label}.view_{model_or_perm._meta.model_name}"
|
||||
)
|
||||
try:
|
||||
user.assign_perms_to_managed_role(code_name, model_or_perm)
|
||||
elif isinstance(model_or_perm, tuple):
|
||||
perm, obj = model_or_perm
|
||||
user.assign_perms_to_managed_role(perm, obj)
|
||||
else:
|
||||
user.assign_perms_to_managed_role(model_or_perm)
|
||||
except (Permission.DoesNotExist, AttributeError) as exc:
|
||||
LOGGER.warning(
|
||||
"permission doesn't exist",
|
||||
code_name=code_name,
|
||||
user=user,
|
||||
model=model_or_perm,
|
||||
)
|
||||
Event.new(
|
||||
action=EventAction.SYSTEM_EXCEPTION,
|
||||
message=(
|
||||
"While setting the permissions for the service-account, a "
|
||||
"permission was not found: Check "
|
||||
"https://docs.goauthentik.io/troubleshooting/missing_permission"
|
||||
),
|
||||
).with_exception(exc).set_user(user).save()
|
||||
except (Permission.DoesNotExist, AttributeError) as exc:
|
||||
LOGGER.warning(
|
||||
"permission doesn't exist",
|
||||
code_name=code_name,
|
||||
user=user,
|
||||
model=model_or_perm,
|
||||
)
|
||||
Event.new(
|
||||
action=EventAction.SYSTEM_EXCEPTION,
|
||||
message=(
|
||||
"While setting the permissions for the service-account, a "
|
||||
"permission was not found: Check "
|
||||
"https://docs.goauthentik.io/troubleshooting/missing_permission"
|
||||
),
|
||||
).with_exception(exc).set_user(user).save()
|
||||
else:
|
||||
app_label, perm = model_or_perm.split(".")
|
||||
permission = Permission.objects.filter(
|
||||
codename=perm,
|
||||
content_type__app_label=app_label,
|
||||
)
|
||||
if not permission.exists():
|
||||
LOGGER.warning("permission doesn't exist", perm=model_or_perm)
|
||||
continue
|
||||
user.assign_perms_to_managed_role(permission.first())
|
||||
LOGGER.debug(
|
||||
"Updated service account's permissions",
|
||||
obj_perms=user.get_all_obj_perms_on_managed_role(),
|
||||
@@ -425,7 +431,7 @@ class Outpost(ScheduledModel, SerializerModel, ManagedModel):
|
||||
Token.objects.filter(identifier=self.token_identifier).delete()
|
||||
return self.token
|
||||
|
||||
def get_required_objects(self) -> Iterable[models.Model | str | tuple[str, models.Model]]:
|
||||
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||
"""Get an iterator of all objects the user needs read access to"""
|
||||
objects: list[models.Model | str] = [
|
||||
self,
|
||||
@@ -439,9 +445,7 @@ class Outpost(ScheduledModel, SerializerModel, ManagedModel):
|
||||
if self.managed:
|
||||
for brand in Brand.objects.filter(web_certificate__isnull=False):
|
||||
objects.append(brand)
|
||||
objects.append(("view_certificatekeypair", brand.web_certificate))
|
||||
objects.append(("view_certificatekeypair_certificate", brand.web_certificate))
|
||||
objects.append(("view_certificatekeypair_key", brand.web_certificate))
|
||||
objects.append(brand.web_certificate)
|
||||
return objects
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
||||
@@ -51,12 +51,10 @@ class OutpostTests(TestCase):
|
||||
permissions = outpost.user.get_all_obj_perms_on_managed_role().order_by(
|
||||
"content_type__model"
|
||||
)
|
||||
self.assertEqual(len(permissions), 5)
|
||||
self.assertEqual(len(permissions), 3)
|
||||
self.assertEqual(permissions[0].object_pk, str(keypair.pk))
|
||||
self.assertEqual(permissions[1].object_pk, str(keypair.pk))
|
||||
self.assertEqual(permissions[2].object_pk, str(keypair.pk))
|
||||
self.assertEqual(permissions[3].object_pk, str(outpost.pk))
|
||||
self.assertEqual(permissions[4].object_pk, str(provider.pk))
|
||||
self.assertEqual(permissions[1].object_pk, str(outpost.pk))
|
||||
self.assertEqual(permissions[2].object_pk, str(provider.pk))
|
||||
|
||||
# Remove provider from outpost, user should only have access to outpost
|
||||
outpost.providers.remove(provider)
|
||||
|
||||
@@ -93,13 +93,11 @@ class LDAPProvider(OutpostModel, BackchannelProvider):
|
||||
def __str__(self):
|
||||
return f"LDAP Provider {self.name}"
|
||||
|
||||
def get_required_objects(self) -> Iterable[models.Model | str | tuple[str, models.Model]]:
|
||||
required = [self, "authentik_core.view_user", "authentik_core.view_group"]
|
||||
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||
required_models = [self, "authentik_core.view_user", "authentik_core.view_group"]
|
||||
if self.certificate is not None:
|
||||
required.append(("view_certificatekeypair", self.certificate))
|
||||
required.append(("view_certificatekeypair_certificate", self.certificate))
|
||||
required.append(("view_certificatekeypair_key", self.certificate))
|
||||
return required
|
||||
required_models.append(self.certificate)
|
||||
return required_models
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("LDAP Provider")
|
||||
|
||||
@@ -179,13 +179,11 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
|
||||
def __str__(self):
|
||||
return f"Proxy Provider {self.name}"
|
||||
|
||||
def get_required_objects(self) -> Iterable[models.Model | str | tuple[str, models.Model]]:
|
||||
required = [self]
|
||||
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||
required_models = [self]
|
||||
if self.certificate is not None:
|
||||
required.append(("view_certificatekeypair", self.certificate))
|
||||
required.append(("view_certificatekeypair_certificate", self.certificate))
|
||||
required.append(("view_certificatekeypair_key", self.certificate))
|
||||
return required
|
||||
required_models.append(self.certificate)
|
||||
return required_models
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Proxy Provider")
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
"""proxy provider tests"""
|
||||
|
||||
from json import loads
|
||||
|
||||
from django.urls import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.outposts.models import Outpost, OutpostType
|
||||
from authentik.providers.oauth2.models import ClientTypes
|
||||
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
|
||||
|
||||
@@ -131,55 +127,3 @@ class ProxyProviderTests(APITestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
provider: ProxyProvider = ProxyProvider.objects.get(name=name)
|
||||
self.assertEqual(provider.client_type, ClientTypes.CONFIDENTIAL)
|
||||
|
||||
def test_sa_fetch(self):
|
||||
"""Test fetching the outpost config as the service account"""
|
||||
outpost = Outpost.objects.create(name=generate_id(), type=OutpostType.PROXY)
|
||||
provider = ProxyProvider.objects.create(name=generate_id())
|
||||
Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
|
||||
outpost.providers.add(provider)
|
||||
|
||||
res = self.client.get(
|
||||
reverse("authentik_api:proxyprovideroutpost-list"),
|
||||
HTTP_AUTHORIZATION=f"Bearer {outpost.token.key}",
|
||||
)
|
||||
body = loads(res.content)
|
||||
self.assertEqual(body["pagination"]["count"], 1)
|
||||
|
||||
def test_sa_perms_cert(self):
|
||||
"""Test permissions to access a configured certificate"""
|
||||
cert = create_test_cert()
|
||||
outpost = Outpost.objects.create(name=generate_id(), type=OutpostType.PROXY)
|
||||
provider = ProxyProvider.objects.create(name=generate_id(), certificate=cert)
|
||||
Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
|
||||
outpost.providers.add(provider)
|
||||
|
||||
res = self.client.get(
|
||||
reverse("authentik_api:proxyprovideroutpost-list"),
|
||||
HTTP_AUTHORIZATION=f"Bearer {outpost.token.key}",
|
||||
)
|
||||
body = loads(res.content)
|
||||
self.assertEqual(body["pagination"]["count"], 1)
|
||||
cert_id = body["results"][0]["certificate"]
|
||||
self.assertEqual(cert_id, str(cert.pk))
|
||||
|
||||
res = self.client.get(
|
||||
reverse(
|
||||
"authentik_api:certificatekeypair-view-certificate",
|
||||
kwargs={
|
||||
"pk": cert_id,
|
||||
},
|
||||
),
|
||||
HTTP_AUTHORIZATION=f"Bearer {outpost.token.key}",
|
||||
)
|
||||
self.assertEqual(res.status_code, 200)
|
||||
# res = self.client.get(
|
||||
# reverse(
|
||||
# "authentik_api:certificatekeypair-view-private-key",
|
||||
# kwargs={
|
||||
# "pk": cert_id,
|
||||
# },
|
||||
# ),
|
||||
# HTTP_AUTHORIZATION=f"Bearer {outpost.token.key}",
|
||||
# )
|
||||
# self.assertEqual(res.status_code, 200)
|
||||
|
||||
@@ -64,12 +64,10 @@ class RadiusProvider(OutpostModel, Provider):
|
||||
|
||||
return RadiusProviderSerializer
|
||||
|
||||
def get_required_objects(self) -> Iterable[models.Model | str | tuple[str, models.Model]]:
|
||||
def get_required_objects(self) -> Iterable[models.Model | str]:
|
||||
required = [self, "authentik_stages_mtls.pass_outpost_certificate"]
|
||||
if self.certificate is not None:
|
||||
required.append(("view_certificatekeypair", self.certificate))
|
||||
required.append(("view_certificatekeypair_certificate", self.certificate))
|
||||
required.append(("view_certificatekeypair_key", self.certificate))
|
||||
required.append(self.certificate)
|
||||
return required
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -9,7 +9,7 @@ from guardian.shortcuts import get_objects_for_user
|
||||
from rest_framework import mixins
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import CharField, ChoiceField, IntegerField
|
||||
from rest_framework.permissions import AllowAny
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
@@ -21,11 +21,9 @@ from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import ModelSerializer
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.flows.auth import FlowActive
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.rbac.decorators import permission_required
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
from authentik.stages.authenticator_duo.stage import PLAN_CONTEXT_DUO_ENROLL
|
||||
from authentik.stages.authenticator_duo.stage import SESSION_KEY_DUO_ENROLL
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
@@ -86,20 +84,14 @@ class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
|
||||
),
|
||||
},
|
||||
)
|
||||
@action(
|
||||
methods=["POST"],
|
||||
detail=True,
|
||||
authentication_classes=[FlowActive],
|
||||
permission_classes=[AllowAny],
|
||||
)
|
||||
@action(methods=["POST"], detail=True, permission_classes=[IsAuthenticated])
|
||||
def enrollment_status(self, request: Request, pk: str) -> Response:
|
||||
"""Check enrollment status of user details in current session"""
|
||||
stage: AuthenticatorDuoStage = AuthenticatorDuoStage.objects.filter(pk=pk).first()
|
||||
if not stage:
|
||||
raise Http404
|
||||
client = stage.auth_client()
|
||||
plan: FlowPlan = request.auth
|
||||
enroll = plan.context.get(PLAN_CONTEXT_DUO_ENROLL)
|
||||
enroll = self.request.session.get(SESSION_KEY_DUO_ENROLL)
|
||||
if not enroll:
|
||||
return Response(status=400)
|
||||
status = client.enroll_status(enroll["user_id"], enroll["activation_code"])
|
||||
|
||||
@@ -14,7 +14,7 @@ from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.flows.views.executor import InvalidStageError
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
|
||||
PLAN_CONTEXT_DUO_ENROLL = "goauthentik.io/stages/authenticator_duo/enroll"
|
||||
SESSION_KEY_DUO_ENROLL = "authentik/stages/authenticator_duo/enroll"
|
||||
|
||||
|
||||
class AuthenticatorDuoChallenge(WithUserInfoChallenge):
|
||||
@@ -50,14 +50,14 @@ class AuthenticatorDuoStageView(ChallengeStageView):
|
||||
user=user,
|
||||
).from_http(self.request, user)
|
||||
raise InvalidStageError(str(exc)) from exc
|
||||
self.executor.plan.context[PLAN_CONTEXT_DUO_ENROLL] = enroll
|
||||
self.request.session[SESSION_KEY_DUO_ENROLL] = enroll
|
||||
return enroll
|
||||
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
stage: AuthenticatorDuoStage = self.executor.current_stage
|
||||
if PLAN_CONTEXT_DUO_ENROLL not in self.executor.plan.context:
|
||||
if SESSION_KEY_DUO_ENROLL not in self.request.session:
|
||||
self.duo_enroll()
|
||||
enroll = self.executor.plan.context[PLAN_CONTEXT_DUO_ENROLL]
|
||||
enroll = self.request.session[SESSION_KEY_DUO_ENROLL]
|
||||
return AuthenticatorDuoChallenge(
|
||||
data={
|
||||
"activation_barcode": enroll["activation_barcode"],
|
||||
@@ -69,14 +69,14 @@ class AuthenticatorDuoStageView(ChallengeStageView):
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
# Duo Challenge has already been validated
|
||||
stage: AuthenticatorDuoStage = self.executor.current_stage
|
||||
enroll = self.executor.plan.context.get(PLAN_CONTEXT_DUO_ENROLL)
|
||||
enroll = self.request.session.get(SESSION_KEY_DUO_ENROLL)
|
||||
enroll_status = stage.auth_client().enroll_status(
|
||||
enroll["user_id"], enroll["activation_code"]
|
||||
)
|
||||
if enroll_status != "success":
|
||||
return self.executor.stage_invalid(f"Invalid enrollment status: {enroll_status}.")
|
||||
existing_device = DuoDevice.objects.filter(duo_user_id=enroll["user_id"]).first()
|
||||
self.executor.plan.context.pop(PLAN_CONTEXT_DUO_ENROLL)
|
||||
self.request.session.pop(SESSION_KEY_DUO_ENROLL)
|
||||
if not existing_device:
|
||||
DuoDevice.objects.create(
|
||||
name="Duo Authenticator",
|
||||
@@ -88,3 +88,6 @@ class AuthenticatorDuoStageView(ChallengeStageView):
|
||||
else:
|
||||
return self.executor.stage_invalid("Device with Credential ID already exists.")
|
||||
return self.executor.stage_ok()
|
||||
|
||||
def cleanup(self):
|
||||
self.request.session.pop(SESSION_KEY_DUO_ENROLL, None)
|
||||
|
||||
@@ -11,6 +11,7 @@ from authentik.flows.models import FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
from authentik.stages.authenticator_duo.stage import SESSION_KEY_DUO_ENROLL
|
||||
from authentik.stages.identification.models import IdentificationStage, UserFields
|
||||
|
||||
|
||||
@@ -50,6 +51,42 @@ class AuthenticatorDuoStageTests(FlowTestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_api_enrollment(self):
|
||||
"""Test `enrollment_status`"""
|
||||
self.client.force_login(self.user)
|
||||
stage = AuthenticatorDuoStage.objects.create(
|
||||
name=generate_id(),
|
||||
client_id=generate_id(),
|
||||
client_secret=generate_id(),
|
||||
api_hostname=generate_id(),
|
||||
)
|
||||
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"authentik_api:authenticatorduostage-enrollment-status",
|
||||
kwargs={
|
||||
"pk": str(stage.pk),
|
||||
},
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_DUO_ENROLL] = {"user_id": "foo", "activation_code": "bar"}
|
||||
session.save()
|
||||
|
||||
with patch("duo_client.auth.Auth.enroll_status", MagicMock(return_value="foo")):
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"authentik_api:authenticatorduostage-enrollment-status",
|
||||
kwargs={
|
||||
"pk": str(stage.pk),
|
||||
},
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content.decode(), '{"duo_response":"foo"}')
|
||||
|
||||
def test_api_import_manual_invalid_username(self):
|
||||
"""Test `import_device_manual`"""
|
||||
self.client.force_login(self.user)
|
||||
@@ -277,17 +314,6 @@ class AuthenticatorDuoStageTests(FlowTestCase):
|
||||
self.assertEqual(enroll_mock.call_count, 1)
|
||||
|
||||
with patch("duo_client.auth.Auth.enroll_status", MagicMock(return_value="success")):
|
||||
response = self.client.post(
|
||||
reverse(
|
||||
"authentik_api:authenticatorduostage-enrollment-status",
|
||||
kwargs={
|
||||
"pk": str(stage.pk),
|
||||
},
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(response.content, {"duo_response": "success"})
|
||||
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), {}
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.http.request import QueryDict
|
||||
from django.template.exceptions import TemplateSyntaxError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import BooleanField, CharField
|
||||
from rest_framework.fields import BooleanField, CharField, IntegerField
|
||||
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import (
|
||||
@@ -26,7 +26,7 @@ from authentik.stages.email.tasks import send_mails
|
||||
from authentik.stages.email.utils import TemplateEmailMessage
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||
|
||||
PLAN_CONTEXT_EMAIL_DEVICE = "goauthentik.io/stages/authenticator_email/email_device"
|
||||
SESSION_KEY_EMAIL_DEVICE = "authentik/stages/authenticator_email/email_device"
|
||||
PLAN_CONTEXT_EMAIL = "email"
|
||||
PLAN_CONTEXT_EMAIL_SENT = "email_sent"
|
||||
PLAN_CONTEXT_EMAIL_OVERRIDE = "email"
|
||||
@@ -47,7 +47,7 @@ class AuthenticatorEmailChallengeResponse(ChallengeResponse):
|
||||
|
||||
device: EmailDevice
|
||||
|
||||
code = CharField(required=False)
|
||||
code = IntegerField(required=False)
|
||||
email = CharField(required=False)
|
||||
|
||||
component = CharField(default="ak-stage-authenticator-email")
|
||||
@@ -79,7 +79,7 @@ class AuthenticatorEmailStageView(ChallengeStageView):
|
||||
if EmailDevice.objects.filter(Q(email=email), stage=stage.pk).exists():
|
||||
raise ValidationError(_("Invalid email"))
|
||||
|
||||
device: EmailDevice = self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
device: EmailDevice = self.request.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
|
||||
try:
|
||||
message = TemplateEmailMessage(
|
||||
@@ -116,9 +116,9 @@ class AuthenticatorEmailStageView(ChallengeStageView):
|
||||
self.logger.debug("got email from plan context")
|
||||
return context.get(PLAN_CONTEXT_PROMPT, {}).get(PLAN_CONTEXT_EMAIL)
|
||||
# Check device for email
|
||||
if PLAN_CONTEXT_EMAIL_DEVICE in self.executor.plan.context:
|
||||
if SESSION_KEY_EMAIL_DEVICE in self.request.session:
|
||||
self.logger.debug("got email from device in session")
|
||||
device: EmailDevice = self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
device: EmailDevice = self.request.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
if device.email == "":
|
||||
return None
|
||||
return device.email
|
||||
@@ -135,7 +135,7 @@ class AuthenticatorEmailStageView(ChallengeStageView):
|
||||
|
||||
def get_response_instance(self, data: QueryDict) -> ChallengeResponse:
|
||||
response = super().get_response_instance(data)
|
||||
response.device = self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
response.device = self.request.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
return response
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
@@ -147,11 +147,11 @@ class AuthenticatorEmailStageView(ChallengeStageView):
|
||||
return self.executor.stage_invalid(
|
||||
_("The user already has an email address registered for MFA.")
|
||||
)
|
||||
if PLAN_CONTEXT_EMAIL_DEVICE not in self.executor.plan.context:
|
||||
if SESSION_KEY_EMAIL_DEVICE not in self.request.session:
|
||||
device = EmailDevice(user=user, confirmed=False, stage=stage, name="Email Device")
|
||||
valid_secs: int = timedelta_from_string(stage.token_expiry).total_seconds()
|
||||
device.generate_token(valid_secs=valid_secs, commit=False)
|
||||
self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE] = device
|
||||
self.request.session[SESSION_KEY_EMAIL_DEVICE] = device
|
||||
if email := self._has_email():
|
||||
device.email = email
|
||||
try:
|
||||
@@ -165,16 +165,16 @@ class AuthenticatorEmailStageView(ChallengeStageView):
|
||||
self.executor.plan.context.get(PLAN_CONTEXT_PROMPT, {}).pop(
|
||||
PLAN_CONTEXT_EMAIL, None
|
||||
)
|
||||
self.executor.plan.context.pop(PLAN_CONTEXT_EMAIL_DEVICE, None)
|
||||
self.request.session.pop(SESSION_KEY_EMAIL_DEVICE, None)
|
||||
self.logger.warning("failed to send email to pre-set address", exc=exc)
|
||||
return self.get(request, *args, **kwargs)
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
"""Email Token is validated by challenge"""
|
||||
device: EmailDevice = self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
device: EmailDevice = self.request.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
if not device.confirmed:
|
||||
return self.challenge_invalid(response)
|
||||
device.save()
|
||||
del self.executor.plan.context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
del self.request.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
return self.executor.stage_ok()
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.template.exceptions import TemplateDoesNotExist
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
|
||||
from authentik.core.tests.utils import create_test_flow, create_test_user
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_user
|
||||
from authentik.flows.models import FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.lib.config import CONFIG
|
||||
@@ -21,7 +21,9 @@ from authentik.stages.authenticator_email.api import (
|
||||
EmailDeviceSerializer,
|
||||
)
|
||||
from authentik.stages.authenticator_email.models import AuthenticatorEmailStage, EmailDevice
|
||||
from authentik.stages.authenticator_email.stage import PLAN_CONTEXT_EMAIL_DEVICE
|
||||
from authentik.stages.authenticator_email.stage import (
|
||||
SESSION_KEY_EMAIL_DEVICE,
|
||||
)
|
||||
from authentik.stages.email.utils import TemplateEmailMessage
|
||||
|
||||
|
||||
@@ -31,7 +33,7 @@ class TestAuthenticatorEmailStage(FlowTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.flow = create_test_flow()
|
||||
self.user = create_test_user()
|
||||
self.user = create_test_admin_user()
|
||||
self.user_noemail = create_test_user(email="")
|
||||
self.stage = AuthenticatorEmailStage.objects.create(
|
||||
name="email-authenticator",
|
||||
@@ -211,26 +213,20 @@ class TestAuthenticatorEmailStage(FlowTestCase):
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={"component": "ak-stage-authenticator-email"},
|
||||
)
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
response_errors={"non_field_errors": [{"code": "invalid", "string": "email required"}]},
|
||||
)
|
||||
self.assertIn("email required", str(response.content))
|
||||
|
||||
# Test invalid code
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={"component": "ak-stage-authenticator-email", "code": "000000"},
|
||||
)
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
response_errors={
|
||||
"non_field_errors": [{"code": "invalid", "string": "Code does not match"}]
|
||||
},
|
||||
)
|
||||
self.assertIn("Code does not match", str(response.content))
|
||||
|
||||
# Test valid code
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
device = self.device
|
||||
token = device.token
|
||||
response = self.client.post(
|
||||
@@ -289,7 +285,8 @@ class TestAuthenticatorEmailStage(FlowTestCase):
|
||||
response = self.client.get(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
device = self.get_flow_plan().context[PLAN_CONTEXT_EMAIL_DEVICE]
|
||||
self.assertIn(SESSION_KEY_EMAIL_DEVICE, self.client.session)
|
||||
device = self.client.session[SESSION_KEY_EMAIL_DEVICE]
|
||||
self.assertIsInstance(device, EmailDevice)
|
||||
self.assertFalse(device.confirmed)
|
||||
self.assertEqual(device.user, self.user)
|
||||
@@ -297,6 +294,8 @@ class TestAuthenticatorEmailStage(FlowTestCase):
|
||||
# Test device confirmation and cleanup
|
||||
device.confirmed = True
|
||||
device.email = "new_test@authentik.local" # Use a different email
|
||||
self.client.session[SESSION_KEY_EMAIL_DEVICE] = device
|
||||
self.client.session.save()
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={"component": "ak-stage-authenticator-email", "code": device.token},
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.http import HttpRequest, HttpResponse
|
||||
from django.http.request import QueryDict
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import BooleanField, CharField
|
||||
from rest_framework.fields import BooleanField, CharField, IntegerField
|
||||
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
@@ -20,7 +20,7 @@ from authentik.stages.authenticator_sms.models import (
|
||||
)
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||
|
||||
PLAN_CONTEXT_SMS_DEVICE = "goauthentik.io/stages/authenticator_sms/sms_device"
|
||||
SESSION_KEY_SMS_DEVICE = "authentik/stages/authenticator_sms/sms_device"
|
||||
PLAN_CONTEXT_PHONE = "phone"
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class AuthenticatorSMSChallengeResponse(ChallengeResponse):
|
||||
|
||||
device: SMSDevice
|
||||
|
||||
code = CharField(required=False)
|
||||
code = IntegerField(required=False)
|
||||
phone_number = CharField(required=False)
|
||||
|
||||
component = CharField(default="ak-stage-authenticator-sms")
|
||||
@@ -70,7 +70,7 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
if SMSDevice.objects.filter(query, stage=stage.pk).exists():
|
||||
raise ValidationError(_("Invalid phone number"))
|
||||
# No code yet, but we have a phone number, so send a verification message
|
||||
device: SMSDevice = self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
device: SMSDevice = self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
stage.send(self.request, device.token, device)
|
||||
|
||||
def _has_phone_number(self) -> str | None:
|
||||
@@ -78,9 +78,9 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
if PLAN_CONTEXT_PHONE in context.get(PLAN_CONTEXT_PROMPT, {}):
|
||||
self.logger.debug("got phone number from plan context")
|
||||
return context.get(PLAN_CONTEXT_PROMPT, {}).get(PLAN_CONTEXT_PHONE)
|
||||
if PLAN_CONTEXT_SMS_DEVICE in self.executor.plan.context:
|
||||
if SESSION_KEY_SMS_DEVICE in self.request.session:
|
||||
self.logger.debug("got phone number from device in session")
|
||||
device: SMSDevice = self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
device: SMSDevice = self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
if device.phone_number == "":
|
||||
return None
|
||||
return device.phone_number
|
||||
@@ -95,7 +95,7 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
|
||||
def get_response_instance(self, data: QueryDict) -> ChallengeResponse:
|
||||
response = super().get_response_instance(data)
|
||||
response.device = self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
response.device = self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
return response
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
@@ -103,10 +103,10 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
|
||||
stage: AuthenticatorSMSStage = self.executor.current_stage
|
||||
|
||||
if PLAN_CONTEXT_SMS_DEVICE not in self.executor.plan.context:
|
||||
if SESSION_KEY_SMS_DEVICE not in self.request.session:
|
||||
device = SMSDevice(user=user, confirmed=False, stage=stage, name="SMS Device")
|
||||
device.generate_token(commit=False)
|
||||
self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE] = device
|
||||
self.request.session[SESSION_KEY_SMS_DEVICE] = device
|
||||
if phone_number := self._has_phone_number():
|
||||
device.phone_number = phone_number
|
||||
try:
|
||||
@@ -120,14 +120,14 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
self.executor.plan.context.get(PLAN_CONTEXT_PROMPT, {}).pop(
|
||||
PLAN_CONTEXT_PHONE, None
|
||||
)
|
||||
self.executor.plan.context.pop(PLAN_CONTEXT_SMS_DEVICE, None)
|
||||
self.request.session.pop(SESSION_KEY_SMS_DEVICE, None)
|
||||
self.logger.warning("failed to send SMS message to pre-set number", exc=exc)
|
||||
return self.get(request, *args, **kwargs)
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
"""SMS Token is validated by challenge"""
|
||||
device: SMSDevice = self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
device: SMSDevice = self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
if not device.confirmed:
|
||||
return self.challenge_invalid(response)
|
||||
stage: AuthenticatorSMSStage = self.executor.current_stage
|
||||
@@ -135,5 +135,5 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
self.logger.debug("Hashing number on device")
|
||||
device.set_hashed_number()
|
||||
device.save()
|
||||
del self.executor.plan.context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
del self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
return self.executor.stage_ok()
|
||||
|
||||
@@ -18,7 +18,7 @@ from authentik.stages.authenticator_sms.models import (
|
||||
SMSProviders,
|
||||
hash_phone_number,
|
||||
)
|
||||
from authentik.stages.authenticator_sms.stage import PLAN_CONTEXT_PHONE, PLAN_CONTEXT_SMS_DEVICE
|
||||
from authentik.stages.authenticator_sms.stage import PLAN_CONTEXT_PHONE, SESSION_KEY_SMS_DEVICE
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ class AuthenticatorSMSStageTests(FlowTestCase):
|
||||
self.assertEqual(mocker.call_count, 1)
|
||||
self.assertEqual(mocker.request_history[0].method, "POST")
|
||||
request_body = dict(parse_qsl(mocker.request_history[0].body))
|
||||
device: SMSDevice = self.get_flow_plan().context[PLAN_CONTEXT_SMS_DEVICE]
|
||||
device: SMSDevice = self.client.session[SESSION_KEY_SMS_DEVICE]
|
||||
self.assertEqual(
|
||||
request_body,
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ from urllib.parse import quote
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.http.request import QueryDict
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.fields import CharField
|
||||
from rest_framework.fields import CharField, IntegerField
|
||||
from rest_framework.serializers import ValidationError
|
||||
|
||||
from authentik.flows.challenge import (
|
||||
@@ -32,10 +32,10 @@ class AuthenticatorTOTPChallengeResponse(ChallengeResponse):
|
||||
|
||||
device: TOTPDevice
|
||||
|
||||
code = CharField()
|
||||
code = IntegerField()
|
||||
component = CharField(default="ak-stage-authenticator-totp")
|
||||
|
||||
def validate_code(self, code: str) -> str:
|
||||
def validate_code(self, code: int) -> int:
|
||||
"""Validate totp code"""
|
||||
if not self.device:
|
||||
raise ValidationError(_("Code does not match"))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"""authentik consent stage"""
|
||||
|
||||
from hmac import compare_digest
|
||||
from uuid import uuid4
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -24,7 +23,7 @@ PLAN_CONTEXT_CONSENT = "consent"
|
||||
PLAN_CONTEXT_CONSENT_HEADER = "consent_header"
|
||||
PLAN_CONTEXT_CONSENT_PERMISSIONS = "consent_permissions"
|
||||
PLAN_CONTEXT_CONSENT_EXTRA_PERMISSIONS = "consent_additional_permissions"
|
||||
PLAN_CONTEXT_CONSENT_TOKEN = "goauthentik.io/stages/consent/token" # nosec
|
||||
SESSION_KEY_CONSENT_TOKEN = "authentik/stages/consent/token" # nosec
|
||||
|
||||
|
||||
class ConsentPermissionSerializer(PassiveSerializer):
|
||||
@@ -51,9 +50,7 @@ class ConsentChallengeResponse(ChallengeResponse):
|
||||
token = CharField(required=True)
|
||||
|
||||
def validate_token(self, token: str):
|
||||
if not compare_digest(
|
||||
token, self.stage.executor.plan.context.get(PLAN_CONTEXT_CONSENT_TOKEN, "")
|
||||
):
|
||||
if token != self.stage.executor.request.session[SESSION_KEY_CONSENT_TOKEN]:
|
||||
raise ValidationError(_("Invalid consent token, re-showing prompt"))
|
||||
return token
|
||||
|
||||
@@ -65,7 +62,7 @@ class ConsentStageView(ChallengeStageView):
|
||||
|
||||
def get_challenge(self) -> Challenge:
|
||||
token = str(uuid4())
|
||||
self.executor.plan.context[PLAN_CONTEXT_CONSENT_TOKEN] = token
|
||||
self.request.session[SESSION_KEY_CONSENT_TOKEN] = token
|
||||
data = {
|
||||
"permissions": self.executor.plan.context.get(PLAN_CONTEXT_CONSENT_PERMISSIONS, []),
|
||||
"additional_permissions": self.executor.plan.context.get(
|
||||
|
||||
@@ -19,7 +19,7 @@ from authentik.stages.consent.models import ConsentMode, ConsentStage, UserConse
|
||||
from authentik.stages.consent.stage import (
|
||||
PLAN_CONTEXT_CONSENT_HEADER,
|
||||
PLAN_CONTEXT_CONSENT_PERMISSIONS,
|
||||
PLAN_CONTEXT_CONSENT_TOKEN,
|
||||
SESSION_KEY_CONSENT_TOKEN,
|
||||
)
|
||||
|
||||
|
||||
@@ -83,10 +83,11 @@ class TestConsentStage(FlowTestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
session = self.client.session
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||
{
|
||||
"token": self.get_flow_plan().context[PLAN_CONTEXT_CONSENT_TOKEN],
|
||||
"token": session[SESSION_KEY_CONSENT_TOKEN],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -121,7 +122,7 @@ class TestConsentStage(FlowTestCase):
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||
{
|
||||
"token": self.get_flow_plan().context[PLAN_CONTEXT_CONSENT_TOKEN],
|
||||
"token": session[SESSION_KEY_CONSENT_TOKEN],
|
||||
},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
@@ -19,7 +19,7 @@ from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import QS_KEY_TOKEN, SESSION_KEY_PLAN, FlowExecutorView
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.stages.consent.stage import PLAN_CONTEXT_CONSENT_TOKEN
|
||||
from authentik.stages.consent.stage import SESSION_KEY_CONSENT_TOKEN
|
||||
from authentik.stages.email.models import EmailStage
|
||||
from authentik.stages.email.stage import PLAN_CONTEXT_EMAIL_OVERRIDE, EmailStageView
|
||||
|
||||
@@ -174,7 +174,7 @@ class TestEmailStage(FlowTestCase):
|
||||
kwargs={"flow_slug": self.flow.slug},
|
||||
),
|
||||
data={
|
||||
"token": self.get_flow_plan().context[PLAN_CONTEXT_CONSENT_TOKEN],
|
||||
"token": self.client.session[SESSION_KEY_CONSENT_TOKEN],
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
|
||||
@@ -245,10 +245,7 @@ class WorkerStatusMiddleware(Middleware):
|
||||
WorkerStatusMiddleware.keep(status)
|
||||
except DB_ERRORS: # pragma: no cover
|
||||
sleep(10)
|
||||
try:
|
||||
connections.close_all()
|
||||
except DB_ERRORS:
|
||||
pass
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def keep(status: WorkerStatus):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||
"type": "object",
|
||||
"title": "authentik 2026.2.0-rc1 Blueprint schema",
|
||||
"title": "authentik 2025.12.0-rc1 Blueprint schema",
|
||||
"required": [
|
||||
"version",
|
||||
"entries"
|
||||
|
||||
@@ -31,13 +31,13 @@ services:
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.0-rc1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.12.0-rc1}
|
||||
ports:
|
||||
- ${COMPOSE_PORT_HTTP:-9000}:9000
|
||||
- ${COMPOSE_PORT_HTTPS:-9443}:9443
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./media:/data/media
|
||||
- ./custom-templates:/templates
|
||||
worker:
|
||||
command: worker
|
||||
@@ -52,12 +52,12 @@ services:
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.0-rc1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.12.0-rc1}
|
||||
restart: unless-stopped
|
||||
user: root
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./data:/data
|
||||
- ./media:/data/media
|
||||
- ./certs:/certs
|
||||
- ./custom-templates:/templates
|
||||
volumes:
|
||||
|
||||
2
go.mod
2
go.mod
@@ -32,7 +32,7 @@ require (
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/wwt/guac v1.3.2
|
||||
goauthentik.io/api/v3 v3.2026020.3
|
||||
goauthentik.io/api/v3 v3.2025120.26
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/sync v0.19.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -214,8 +214,8 @@ go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
goauthentik.io/api/v3 v3.2026020.3 h1:CKtPyAQToPT2yF5odTTc+IfPLhYeVX9FbLMeVnFgZps=
|
||||
goauthentik.io/api/v3 v3.2026020.3/go.mod h1:82lqAz4jxzl6Cg0YDbhNtvvTG2rm6605ZhdJFnbbsl8=
|
||||
goauthentik.io/api/v3 v3.2025120.26 h1:2lTMtjCWtdOeQe7kwjpGUx39qUEpcxcxTirIqMvn0Os=
|
||||
goauthentik.io/api/v3 v3.2025120.26/go.mod h1:82lqAz4jxzl6Cg0YDbhNtvvTG2rm6605ZhdJFnbbsl8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
|
||||
@@ -1 +1 @@
|
||||
2026.2.0-rc1
|
||||
2025.12.0-rc1
|
||||
@@ -28,7 +28,7 @@ func (ps *ProxyServer) Refresh() error {
|
||||
return err
|
||||
}
|
||||
ps.log.WithField("count", len(providers)).Debug("Fetched providers")
|
||||
if len(providers) == 0 && !ps.akAPI.IsEmbedded() {
|
||||
if len(providers) == 0 {
|
||||
ps.log.Warning("No providers assigned to this outpost, check outpost configuration in authentik")
|
||||
}
|
||||
for i, p := range providers {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:8e8f9c84609b6005af0a4a8227cee53d6226aab1c6dcb22daf5aeeb8b05480e1 AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:5d35fb8d28b9095d123b7d96095bbf3750ff18be0a87e5a21c9cffc4351fbf96 AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@@ -31,7 +31,7 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
go build -o /go/ldap ./cmd/ldap
|
||||
|
||||
# Stage 2: Run
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:10dadf1df1337e8eb4218acef6a3027abebf0a155a95d792af736f85ab0e9588
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:07f41ce3f15b2bb5eb5bcd4e6efc0cb42bb7e5609e7244f636da1a91166817ca
|
||||
|
||||
ARG VERSION
|
||||
ARG GIT_BUILD_HASH
|
||||
|
||||
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.1100.1",
|
||||
"aws-cdk": "^2.1033.0",
|
||||
"cross-env": "^10.1.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -25,9 +25,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/aws-cdk": {
|
||||
"version": "2.1100.1",
|
||||
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1100.1.tgz",
|
||||
"integrity": "sha512-q2poFrQh90TK6eqeI0zznA8r1JkDI63WVOSqC7gFGo6qjQjAnvFk/utxHoNRgAC0RL0CLd19uCcHh3jfX9NiSg==",
|
||||
"version": "2.1033.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1033.0.tgz",
|
||||
"integrity": "sha512-Pit2k7cVAwxoYI7RMVsOyltuy7/HGENLupJ4KAm/d8mGzOfX+SLOo9YQsx5CKY9J6ErCZ1ViLerklTfjytvQww==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"aws-cfn": "cross-env CI=false cdk synth --version-reporting=false > template.yaml"
|
||||
},
|
||||
"devDependencies": {
|
||||
"aws-cdk": "^2.1100.1",
|
||||
"aws-cdk": "^2.1033.0",
|
||||
"cross-env": "^10.1.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -18,7 +18,7 @@ Parameters:
|
||||
Description: authentik Docker image
|
||||
AuthentikVersion:
|
||||
Type: String
|
||||
Default: 2026.2.0-rc1
|
||||
Default: 2025.12.0-rc1
|
||||
Description: authentik Docker image tag
|
||||
AuthentikServerCPU:
|
||||
Type: Number
|
||||
|
||||
Binary file not shown.
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-17 00:10+0000\n"
|
||||
"POT-Creation-Date: 2025-12-12 15:51+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -558,30 +558,6 @@ msgid ""
|
||||
"encryption."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "Key algorithm type detected from the certificate's public key"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "Certificate expiry date"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "Certificate subject as RFC4514 string"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "SHA256 fingerprint of the certificate"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "SHA1 fingerprint of the certificate"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "Key ID generated from private key"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "Certificate-Key Pair"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2026.2.0-rc1",
|
||||
"version": "2025.12.0-rc1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2026.2.0-rc1",
|
||||
"version": "2025.12.0-rc1",
|
||||
"dependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@goauthentik/eslint-config": "./packages/eslint-config",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2026.2.0-rc1",
|
||||
"version": "2025.12.0-rc1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -17,7 +17,7 @@ COPY web .
|
||||
RUN npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:8e8f9c84609b6005af0a4a8227cee53d6226aab1c6dcb22daf5aeeb8b05480e1 AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:5d35fb8d28b9095d123b7d96095bbf3750ff18be0a87e5a21c9cffc4351fbf96 AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@@ -47,7 +47,7 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
go build -o /go/proxy ./cmd/proxy
|
||||
|
||||
# Stage 3: Run
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:10dadf1df1337e8eb4218acef6a3027abebf0a155a95d792af736f85ab0e9588
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:07f41ce3f15b2bb5eb5bcd4e6efc0cb42bb7e5609e7244f636da1a91166817ca
|
||||
|
||||
ARG VERSION
|
||||
ARG GIT_BUILD_HASH
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "authentik"
|
||||
version = "2026.2.0-rc1"
|
||||
version = "2025.12.0-rc1"
|
||||
description = ""
|
||||
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
|
||||
requires-python = "==3.13.*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:8e8f9c84609b6005af0a4a8227cee53d6226aab1c6dcb22daf5aeeb8b05480e1 AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:5d35fb8d28b9095d123b7d96095bbf3750ff18be0a87e5a21c9cffc4351fbf96 AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:8e8f9c84609b6005af0a4a8227cee53d6226aab1c6dcb22daf5aeeb8b05480e1 AS builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.5-trixie@sha256:5d35fb8d28b9095d123b7d96095bbf3750ff18be0a87e5a21c9cffc4351fbf96 AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@@ -31,7 +31,7 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
go build -o /go/radius ./cmd/radius
|
||||
|
||||
# Stage 2: Run
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:10dadf1df1337e8eb4218acef6a3027abebf0a155a95d792af736f85ab0e9588
|
||||
FROM ghcr.io/goauthentik/fips-debian:trixie-slim-fips@sha256:07f41ce3f15b2bb5eb5bcd4e6efc0cb42bb7e5609e7244f636da1a91166817ca
|
||||
|
||||
ARG VERSION
|
||||
ARG GIT_BUILD_HASH
|
||||
|
||||
35
schema.yml
35
schema.yml
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2026.2.0-rc1
|
||||
version: 2025.12.0-rc1
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@goauthentik.io
|
||||
@@ -4728,6 +4728,11 @@ paths:
|
||||
schema:
|
||||
type: boolean
|
||||
description: Only return certificate-key pairs with keys
|
||||
- in: query
|
||||
name: include_details
|
||||
schema:
|
||||
type: boolean
|
||||
default: true
|
||||
- in: query
|
||||
name: key_type
|
||||
schema:
|
||||
@@ -33581,8 +33586,7 @@ components:
|
||||
minLength: 1
|
||||
default: ak-stage-authenticator-email
|
||||
code:
|
||||
type: string
|
||||
minLength: 1
|
||||
type: integer
|
||||
email:
|
||||
type: string
|
||||
minLength: 1
|
||||
@@ -33829,8 +33833,7 @@ components:
|
||||
minLength: 1
|
||||
default: ak-stage-authenticator-sms
|
||||
code:
|
||||
type: string
|
||||
minLength: 1
|
||||
type: integer
|
||||
phone_number:
|
||||
type: string
|
||||
minLength: 1
|
||||
@@ -34104,8 +34107,7 @@ components:
|
||||
minLength: 1
|
||||
default: ak-stage-authenticator-totp
|
||||
code:
|
||||
type: string
|
||||
minLength: 1
|
||||
type: integer
|
||||
required:
|
||||
- code
|
||||
AuthenticatorTOTPStage:
|
||||
@@ -34990,25 +34992,25 @@ components:
|
||||
type: string
|
||||
fingerprint_sha256:
|
||||
type: string
|
||||
readOnly: true
|
||||
nullable: true
|
||||
description: SHA256 fingerprint of the certificate
|
||||
description: Get certificate Hash (SHA256)
|
||||
readOnly: true
|
||||
fingerprint_sha1:
|
||||
type: string
|
||||
readOnly: true
|
||||
nullable: true
|
||||
description: SHA1 fingerprint of the certificate
|
||||
description: Get certificate Hash (SHA1)
|
||||
readOnly: true
|
||||
cert_expiry:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
nullable: true
|
||||
description: Certificate expiry date
|
||||
description: Get certificate expiry
|
||||
readOnly: true
|
||||
cert_subject:
|
||||
type: string
|
||||
readOnly: true
|
||||
nullable: true
|
||||
description: Certificate subject as RFC4514 string
|
||||
description: Get certificate subject as full rfc4514
|
||||
readOnly: true
|
||||
private_key_available:
|
||||
type: boolean
|
||||
description: Show if this keypair has a private key configured or not
|
||||
@@ -35016,9 +35018,8 @@ components:
|
||||
key_type:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/KeyTypeEnum'
|
||||
readOnly: true
|
||||
nullable: true
|
||||
description: Key algorithm type detected from the certificate's public key
|
||||
readOnly: true
|
||||
certificate_download_url:
|
||||
type: string
|
||||
description: Get URL to download certificate
|
||||
|
||||
6
scripts/generate_docker_compose.py
Executable file → Normal file
6
scripts/generate_docker_compose.py
Executable file → Normal file
@@ -1,5 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from yaml import safe_dump
|
||||
|
||||
from authentik import authentik_version
|
||||
@@ -44,7 +42,7 @@ base = {
|
||||
"image": authentik_image,
|
||||
"ports": ["${COMPOSE_PORT_HTTP:-9000}:9000", "${COMPOSE_PORT_HTTPS:-9443}:9443"],
|
||||
"restart": "unless-stopped",
|
||||
"volumes": ["./data:/data", "./custom-templates:/templates"],
|
||||
"volumes": ["./media:/data/media", "./custom-templates:/templates"],
|
||||
},
|
||||
"worker": {
|
||||
"command": "worker",
|
||||
@@ -64,7 +62,7 @@ base = {
|
||||
"user": "root",
|
||||
"volumes": [
|
||||
"/var/run/docker.sock:/var/run/docker.sock",
|
||||
"./data:/data",
|
||||
"./media:/data/media",
|
||||
"./certs:/certs",
|
||||
"./custom-templates:/templates",
|
||||
],
|
||||
|
||||
@@ -249,60 +249,36 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
|
||||
Raises a clear test failure if the element isn't found, the text doesn't appear
|
||||
within `timeout` seconds, or the text is not valid JSON.
|
||||
"""
|
||||
use_body = context is None
|
||||
wait_timeout = timeout or self.wait_timeout
|
||||
|
||||
def get_context() -> WebElement:
|
||||
"""Get or refresh the context element."""
|
||||
if use_body:
|
||||
return self.driver.find_element(By.TAG_NAME, "body")
|
||||
return context
|
||||
|
||||
def get_text_safely() -> str:
|
||||
"""Get element text, re-finding element if stale."""
|
||||
for _ in range(5):
|
||||
try:
|
||||
return get_context().text.strip()
|
||||
except StaleElementReferenceException:
|
||||
sleep(0.5)
|
||||
return get_context().text.strip()
|
||||
|
||||
def get_inner_html_safely() -> str:
|
||||
"""Get innerHTML, re-finding element if stale."""
|
||||
for _ in range(5):
|
||||
try:
|
||||
return get_context().get_attribute("innerHTML") or ""
|
||||
except StaleElementReferenceException:
|
||||
sleep(0.5)
|
||||
return get_context().get_attribute("innerHTML") or ""
|
||||
|
||||
try:
|
||||
get_context()
|
||||
if context is None:
|
||||
context = self.driver.find_element(By.TAG_NAME, "body")
|
||||
except NoSuchElementException:
|
||||
self.fail(
|
||||
f"No element found (defaulted to <body>). Current URL: {self.driver.current_url}"
|
||||
)
|
||||
|
||||
wait = WebDriverWait(self.driver, wait_timeout)
|
||||
wait_timeout = timeout or self.wait_timeout
|
||||
wait = WebDriverWait(context, wait_timeout)
|
||||
|
||||
try:
|
||||
wait.until(lambda d: len(get_text_safely()) != 0)
|
||||
wait.until(lambda d: len(d.text.strip()) != 0)
|
||||
except TimeoutException:
|
||||
snippet = get_text_safely()[:500].replace("\n", " ")
|
||||
snippet = context.text.strip()[:500].replace("\n", " ")
|
||||
self.fail(
|
||||
f"Timed out waiting for element text to appear at {self.driver.current_url}. "
|
||||
f"Current content: {snippet or '<empty>'}"
|
||||
)
|
||||
|
||||
body_text = get_text_safely()
|
||||
inner_html = get_inner_html_safely()
|
||||
body_text = context.text.strip()
|
||||
inner_html = context.get_attribute("innerHTML") or ""
|
||||
|
||||
if "redirecting" in inner_html.lower():
|
||||
try:
|
||||
wait.until(lambda d: "redirecting" not in get_inner_html_safely().lower())
|
||||
wait.until(lambda d: "redirecting" not in d.get_attribute("innerHTML").lower())
|
||||
except TimeoutException:
|
||||
snippet = get_text_safely()[:500].replace("\n", " ")
|
||||
inner_html = get_inner_html_safely()
|
||||
snippet = context.text.strip()[:500].replace("\n", " ")
|
||||
inner_html = context.get_attribute("innerHTML") or ""
|
||||
|
||||
self.fail(
|
||||
f"Timed out waiting for redirect to finish at {self.driver.current_url}. "
|
||||
@@ -310,8 +286,8 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
|
||||
f"{inner_html or '<empty>'}"
|
||||
)
|
||||
|
||||
inner_html = get_inner_html_safely()
|
||||
body_text = get_text_safely()
|
||||
inner_html = context.get_attribute("innerHTML") or ""
|
||||
body_text = context.text.strip()
|
||||
|
||||
snippet = body_text[:500].replace("\n", " ")
|
||||
|
||||
|
||||
2
uv.lock
generated
2
uv.lock
generated
@@ -185,7 +185,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "authentik"
|
||||
version = "2026.2.0rc1"
|
||||
version = "2025.12.0rc1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "ak-guardian" },
|
||||
|
||||
1617
web/package-lock.json
generated
1617
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@goauthentik/web",
|
||||
"version": "2026.2.0-rc1",
|
||||
"version": "2025.12.0-rc1",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -93,15 +93,15 @@
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/legacy-modes": "^6.5.2",
|
||||
"@codemirror/theme-one-dark": "^6.1.3",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@floating-ui/dom": "^1.7.4",
|
||||
"@formatjs/intl-listformat": "^7.7.13",
|
||||
"@fortawesome/fontawesome-free": "^7.1.0",
|
||||
"@goauthentik/api": "^2025.10.0-rc1-1760614339",
|
||||
"@goauthentik/core": "^1.0.0",
|
||||
"@goauthentik/esbuild-plugin-live-reload": "^1.4.0",
|
||||
"@goauthentik/eslint-config": "^1.2.0",
|
||||
"@goauthentik/prettier-config": "^3.3.1",
|
||||
"@goauthentik/esbuild-plugin-live-reload": "^1.3.1",
|
||||
"@goauthentik/eslint-config": "^1.1.1",
|
||||
"@goauthentik/prettier-config": "^3.2.1",
|
||||
"@goauthentik/tsconfig": "^1.0.5",
|
||||
"@hcaptcha/types": "^1.1.0",
|
||||
"@lit/context": "^1.1.6",
|
||||
@@ -117,20 +117,20 @@
|
||||
"@patternfly/elements": "^4.2.0",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@playwright/test": "^1.57.0",
|
||||
"@sentry/browser": "^10.31.0",
|
||||
"@storybook/addon-docs": "^10.1.10",
|
||||
"@storybook/addon-links": "^10.1.10",
|
||||
"@storybook/web-components": "^10.1.10",
|
||||
"@storybook/web-components-vite": "^10.1.10",
|
||||
"@sentry/browser": "^10.29.0",
|
||||
"@storybook/addon-docs": "^10.1.6",
|
||||
"@storybook/addon-links": "^10.1.6",
|
||||
"@storybook/web-components": "^10.1.6",
|
||||
"@storybook/web-components-vite": "^10.1.6",
|
||||
"@types/codemirror": "^5.60.17",
|
||||
"@types/grecaptcha": "^3.0.9",
|
||||
"@types/guacamole-common-js": "^1.5.5",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/node": "^25.0.0",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
||||
"@typescript-eslint/parser": "^8.50.0",
|
||||
"@vitest/browser": "^4.0.16",
|
||||
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
||||
"@typescript-eslint/parser": "^8.47.0",
|
||||
"@vitest/browser": "^4.0.15",
|
||||
"@vitest/browser-playwright": "^4.0.15",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
@@ -143,15 +143,15 @@
|
||||
"date-fns": "^4.1.0",
|
||||
"deepmerge-ts": "^7.1.5",
|
||||
"dompurify": "^3.3.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"esbuild": "^0.27.1",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-lit": "^2.1.1",
|
||||
"eslint-plugin-wc": "^3.0.2",
|
||||
"fuse.js": "^7.1.0",
|
||||
"globals": "^16.5.0",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"hastscript": "^9.0.1",
|
||||
"knip": "^5.75.1",
|
||||
"knip": "^5.73.1",
|
||||
"lex": "^2025.11.0",
|
||||
"lit": "^3.3.1",
|
||||
"lit-analyzer": "^2.0.3",
|
||||
@@ -165,8 +165,8 @@
|
||||
"prettier": "^3.6.2",
|
||||
"pseudolocale": "^2.2.0",
|
||||
"rapidoc": "^9.3.8",
|
||||
"react": "^19.2.3",
|
||||
"react-dom": "^19.2.3",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"rehype-highlight": "^7.0.2",
|
||||
"rehype-mermaid": "^3.0.0",
|
||||
"rehype-parse": "^9.0.1",
|
||||
@@ -182,9 +182,9 @@
|
||||
"turnstile-types": "^1.2.3",
|
||||
"type-fest": "^5.3.1",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.50.0",
|
||||
"typescript-eslint": "^8.49.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vite": "^7.3.0",
|
||||
"vite": "^7.2.7",
|
||||
"vitest": "^4.0.15",
|
||||
"webcomponent-qr-code": "^1.3.0",
|
||||
"wireit": "^0.14.12",
|
||||
@@ -194,10 +194,10 @@
|
||||
"@esbuild/darwin-arm64": "^0.27.0",
|
||||
"@esbuild/linux-arm64": "^0.27.0",
|
||||
"@esbuild/linux-x64": "^0.27.0",
|
||||
"@rollup/rollup-darwin-arm64": "^4.53.5",
|
||||
"@rollup/rollup-linux-arm64-gnu": "^4.53.5",
|
||||
"@rollup/rollup-linux-x64-gnu": "^4.53.5",
|
||||
"chromedriver": "^143.0.2"
|
||||
"@rollup/rollup-darwin-arm64": "^4.53.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "^4.53.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "^4.53.3",
|
||||
"chromedriver": "^143.0.0"
|
||||
},
|
||||
"wireit": {
|
||||
"build": {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@goauthentik/tsconfig": "^1.0.5",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/node": "^25.0.0",
|
||||
"@types/semver": "^7.7.1",
|
||||
"semver": "^7.7.3",
|
||||
"typescript": "^5.9.3"
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@rollup/plugin-swc": "^0.4.0",
|
||||
"@swc/cli": "^0.7.9",
|
||||
"@swc/core": "^1.15.6",
|
||||
"@swc/core": "^1.15.3",
|
||||
"base64-js": "^1.5.1",
|
||||
"bootstrap": "^5.3.8",
|
||||
"formdata-polyfill": "^2025.11.0",
|
||||
"globby": "16.0.0",
|
||||
"jquery": "^3.7.1",
|
||||
"rollup": "^4.53.5",
|
||||
"rollup": "^4.53.3",
|
||||
"weakmap-polyfill": "^2.0.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
||||
@@ -99,9 +99,6 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
const alertMsg = msg(
|
||||
"Using this form will only create an Application. In order to authenticate with the application, you will have to manually pair it with a Provider.",
|
||||
);
|
||||
const providerFromInstance = this.instance?.provider;
|
||||
const providerValue = providerFromInstance ?? this.provider;
|
||||
const providerPrefilled = !this.instance && this.provider !== undefined;
|
||||
|
||||
return html`
|
||||
${this.instance ? nothing : html`<ak-alert level="pf-m-info">${alertMsg}</ak-alert>`}
|
||||
@@ -137,10 +134,9 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
<ak-provider-search-input
|
||||
name="provider"
|
||||
label=${msg("Provider")}
|
||||
.value=${providerValue}
|
||||
.readOnly=${providerPrefilled}
|
||||
?blankable=${!providerPrefilled}
|
||||
value=${ifPresent(this.instance?.provider)}
|
||||
help=${msg("Select a provider that this application should use.")}
|
||||
blankable
|
||||
></ak-provider-search-input>
|
||||
<ak-backchannel-providers-input
|
||||
name="backchannelProviders"
|
||||
|
||||
@@ -13,7 +13,6 @@ import { Provider, ProvidersAllListRequest, ProvidersApi } from "@goauthentik/ap
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
const renderElement = (item: Provider) => item.name;
|
||||
const renderValue = (item: Provider | undefined) => item?.pk;
|
||||
@@ -54,9 +53,6 @@ export class AkProviderInput extends AKElement {
|
||||
@property({ type: Number })
|
||||
value?: number;
|
||||
|
||||
@property({ type: Boolean, attribute: "readonly" })
|
||||
readOnly = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@@ -80,8 +76,6 @@ export class AkProviderInput extends AKElement {
|
||||
};
|
||||
|
||||
render() {
|
||||
const readOnlyValue = this.readOnly && typeof this.value === "number";
|
||||
|
||||
return html` <ak-form-element-horizontal name=${this.name}>
|
||||
${AKLabel(
|
||||
{
|
||||
@@ -92,9 +86,7 @@ export class AkProviderInput extends AKElement {
|
||||
},
|
||||
this.label,
|
||||
)}
|
||||
${readOnlyValue
|
||||
? html`<input type="hidden" name=${this.name} value=${this.value ?? ""} />`
|
||||
: nothing}
|
||||
|
||||
<ak-search-select
|
||||
.fieldID=${this.fieldID}
|
||||
.selected=${this.#selected}
|
||||
@@ -102,9 +94,7 @@ export class AkProviderInput extends AKElement {
|
||||
.renderElement=${renderElement}
|
||||
.value=${renderValue}
|
||||
.groupBy=${doGroupBy}
|
||||
?blankable=${readOnlyValue ? false : !!this.blankable}
|
||||
?readonly=${this.readOnly}
|
||||
name=${ifDefined(readOnlyValue ? undefined : this.name)}
|
||||
?blankable=${!!this.blankable}
|
||||
>
|
||||
</ak-search-select>
|
||||
${this.help ? html`<p class="pf-c-form__helper-text">${this.help}</p>` : nothing}
|
||||
|
||||
@@ -67,9 +67,24 @@ export class AkCryptoCertificateSearch extends CustomListenerElement(AKElement)
|
||||
@property({ type: Boolean, attribute: "singleton" })
|
||||
public singleton = false;
|
||||
|
||||
/**
|
||||
* Set to `true` to include certificate details (fingerprints, expiry, certificate subject, key type)
|
||||
* in the API response.
|
||||
* Each returned certificate's PEM data must be parsed using cryptography library,
|
||||
* public keys extracted, and hashes computed. With large result sets, this can add a lot of time
|
||||
* to responses.
|
||||
* Only enable when you actually need the detailed fields displayed in the UI.
|
||||
* For simple certificate selection dropdowns, leave this as `false` (default).
|
||||
* @attr
|
||||
*/
|
||||
@property({ type: Boolean, attribute: "include-details" })
|
||||
public includeDetails = false;
|
||||
|
||||
/**
|
||||
* When allowedKeyTypes is set, only certificates or keypairs with matching
|
||||
* key algorithms will be shown.
|
||||
* key algorithms will be shown. Since certificates must be parsed to
|
||||
* extract algorithm details, an instance with many certificates may experience
|
||||
* long delays and server performance slowdowns. Avoid setting this field whenever possible.
|
||||
* @attr
|
||||
* @example [KeyTypeEnum.Rsa, KeyTypeEnum.Ec]
|
||||
*/
|
||||
@@ -108,6 +123,7 @@ export class AkCryptoCertificateSearch extends CustomListenerElement(AKElement)
|
||||
const args: CryptoCertificatekeypairsListRequest = {
|
||||
ordering: "name",
|
||||
hasKey: !this.noKey,
|
||||
includeDetails: this.includeDetails,
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
|
||||
@@ -45,9 +45,9 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||
static styles: CSSResult[] = [...super.styles, PFDescriptionList];
|
||||
|
||||
async apiEndpoint(): Promise<PaginatedResponse<CertificateKeyPair>> {
|
||||
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
|
||||
...(await this.defaultEndpointConfig()),
|
||||
});
|
||||
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList(
|
||||
await this.defaultEndpointConfig(),
|
||||
);
|
||||
}
|
||||
|
||||
protected columns: TableColumn[] = [
|
||||
|
||||
@@ -77,11 +77,7 @@ export class AgentConnectorSetup extends AKElement {
|
||||
<p>${msg("Afterwards, select the enrollment token you want to use:")}</p>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-12-col">
|
||||
<p>
|
||||
${msg(
|
||||
"Next, download the configuration to deploy the authentik Agent via MDM",
|
||||
)}
|
||||
</p>
|
||||
<p>${msg("Then download the configuration to deploy the authentik Agent")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-6-col pf-l-grid">
|
||||
|
||||
@@ -77,13 +77,10 @@ export class EnrollmentTokenForm extends WithBrandConfig(ModelForm<EnrollmentTok
|
||||
value=${ifDefined(this.instance?.name)}
|
||||
required
|
||||
></ak-text-input>
|
||||
<ak-form-element-horizontal label=${msg("Device Access Group")} name="deviceGroup">
|
||||
<ak-form-element-horizontal label=${msg("Device Group")} name="deviceGroup">
|
||||
<ak-endpoints-device-group-search
|
||||
.group=${this.instance?.deviceGroup}
|
||||
></ak-endpoints-device-group-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Select a device access group to be added to upon enrollment.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="expiring">
|
||||
<label class="pf-c-switch">
|
||||
|
||||
@@ -68,7 +68,7 @@ export class DeviceViewPage extends AKElement {
|
||||
? msg(str`Device ${this.device?.name}`)
|
||||
: msg("Loading device..."),
|
||||
description: this.device?.facts.data.os
|
||||
? `${this.device?.facts.data.os?.name} ${this.device?.facts.data.os?.version}`
|
||||
? this.device?.facts.data.os?.name + " " + this.device?.facts.data.os?.version
|
||||
: undefined,
|
||||
icon: "fa fa-laptop",
|
||||
});
|
||||
@@ -110,7 +110,7 @@ export class DeviceViewPage extends AKElement {
|
||||
?good=${this.device.facts.data.network?.firewallEnabled}
|
||||
></ak-status-label>`,
|
||||
],
|
||||
[msg("Device access group"), this.device.accessGroupObj?.name ?? "-"],
|
||||
[msg("Group"), this.device.accessGroupObj?.name ?? "-"],
|
||||
[
|
||||
msg("Actions"),
|
||||
html`<ak-forms-modal>
|
||||
@@ -162,13 +162,13 @@ export class DeviceViewPage extends AKElement {
|
||||
></ak-status-label>`,
|
||||
],
|
||||
[
|
||||
msg("Primary disk size"),
|
||||
msg("Disk size"),
|
||||
rootDisk?.capacityTotalBytes
|
||||
? getSize(rootDisk.capacityTotalBytes)
|
||||
: "-",
|
||||
],
|
||||
[
|
||||
msg("Primary disk usage"),
|
||||
msg("Disk usage"),
|
||||
rootDisk?.capacityTotalBytes && rootDisk.capacityUsedBytes
|
||||
? html`<progress
|
||||
value="${rootDisk.capacityUsedBytes}"
|
||||
|
||||
@@ -91,20 +91,6 @@ export class DataExportListPage extends TablePage<DataExport> {
|
||||
</div>
|
||||
</dl>`;
|
||||
}
|
||||
|
||||
protected renderEmpty(_inner?: TemplateResult): TemplateResult {
|
||||
return super.renderEmpty(
|
||||
html`<ak-empty-state icon=${this.pageIcon}
|
||||
><span
|
||||
>${msg(
|
||||
html`To create a data export, navigate to
|
||||
<a href="#/identity/users">Directory > Users</a> or to
|
||||
<a href="#/events/log">Events > Logs</a>.`,
|
||||
)}</span
|
||||
>
|
||||
</ak-empty-state>`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -16,33 +16,18 @@ import { createRef, ref } from "lit/directives/ref.js";
|
||||
|
||||
// Same regex is used in the backend as well
|
||||
const VALID_FILE_NAME_PATTERN = /^[a-zA-Z0-9._/-]+$/;
|
||||
|
||||
// Note: browsers compile `pattern` using the new `v` RegExp flag (Unicode sets). Under `/v`,
|
||||
// both `/` and `-` must be escaped inside character classes.
|
||||
const VALID_FILE_NAME_PATTERN_STRING = "^[a-zA-Z0-9._\\/\\-]+$";
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
|
||||
// This is perfect for the "pattern" attribute
|
||||
const VALID_FILE_NAME_PATTERN_STRING = VALID_FILE_NAME_PATTERN.source;
|
||||
|
||||
function assertValidFileName(fileName: string): void {
|
||||
if (!VALID_FILE_NAME_PATTERN.test(fileName)) {
|
||||
throw new Error(
|
||||
msg(
|
||||
"Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes",
|
||||
),
|
||||
msg("Filename can only contain letters, numbers, dots, hyphens, and underscores"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getFileExtension(fileName: string): string {
|
||||
const lastDot = fileName.lastIndexOf(".");
|
||||
if (lastDot <= 0) return "";
|
||||
return fileName.slice(lastDot);
|
||||
}
|
||||
|
||||
function hasBasenameExtension(fileName: string): boolean {
|
||||
const baseName = fileName.split("/").pop() ?? fileName;
|
||||
const lastDot = baseName.lastIndexOf(".");
|
||||
return lastDot > 0;
|
||||
}
|
||||
|
||||
@customElement("ak-file-upload-form")
|
||||
export class FileUploadForm extends Form<Record<string, unknown>> {
|
||||
@property({ type: String, useDefault: true })
|
||||
@@ -72,36 +57,36 @@ export class FileUploadForm extends Form<Record<string, unknown>> {
|
||||
throw new PreventFormSubmit("Selected file not provided", this);
|
||||
}
|
||||
|
||||
assertValidFileName(this.selectedFile.name);
|
||||
|
||||
const api = new AdminApi(DEFAULT_CONFIG);
|
||||
const customName = typeof data.name === "string" ? data.name.trim() : "";
|
||||
const customName = typeof data.fileName === "string" ? data.fileName.trim() : "";
|
||||
|
||||
// If custom name provided, validate and append original extension
|
||||
// Only validate the original filename if no custom name is provided
|
||||
let finalName = this.selectedFile.name;
|
||||
if (customName) {
|
||||
assertValidFileName(customName);
|
||||
const ext = getFileExtension(this.selectedFile.name);
|
||||
finalName =
|
||||
ext && !hasBasenameExtension(customName) ? `${customName}${ext}` : customName;
|
||||
} else {
|
||||
assertValidFileName(this.selectedFile.name);
|
||||
const ext = this.selectedFile.name.substring(this.selectedFile.name.lastIndexOf("."));
|
||||
finalName = customName + ext;
|
||||
}
|
||||
|
||||
assertValidFileName(finalName);
|
||||
return api
|
||||
.adminFileCreate({
|
||||
file: this.selectedFile,
|
||||
name: finalName,
|
||||
usage: this.usage,
|
||||
})
|
||||
.then(() => {
|
||||
showMessage({
|
||||
level: MessageLevel.success,
|
||||
message: msg("File uploaded successfully"),
|
||||
});
|
||||
|
||||
await api.adminFileCreate({
|
||||
file: this.selectedFile,
|
||||
name: finalName,
|
||||
usage: this.usage,
|
||||
});
|
||||
|
||||
showMessage({
|
||||
level: MessageLevel.success,
|
||||
message: msg("File uploaded successfully"),
|
||||
});
|
||||
|
||||
this.reset();
|
||||
this.clearFileInput();
|
||||
this.reset();
|
||||
})
|
||||
.finally(() => {
|
||||
this.clearFileInput();
|
||||
});
|
||||
}
|
||||
|
||||
renderForm() {
|
||||
@@ -116,7 +101,7 @@ export class FileUploadForm extends Form<Record<string, unknown>> {
|
||||
@change=${this.#fileChangeListener}
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("File Name")} name="name">
|
||||
<ak-form-element-horizontal label=${msg("File Name")} name="fileName">
|
||||
<input
|
||||
type="text"
|
||||
class="pf-c-form-control"
|
||||
|
||||
@@ -71,45 +71,40 @@ export class RoleObjectPermissionForm extends ModelForm<RoleAssignData, number>
|
||||
if (!this.modelPermissions) {
|
||||
return nothing;
|
||||
}
|
||||
return html`<span
|
||||
>${msg(
|
||||
"Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.",
|
||||
)}</span
|
||||
>
|
||||
<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${msg("Role")} name="role">
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<Role[]> => {
|
||||
const args: RbacRolesListRequest = {
|
||||
ordering: "name",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const roles = await new RbacApi(DEFAULT_CONFIG).rbacRolesList(args);
|
||||
return roles.results;
|
||||
}}
|
||||
.renderElement=${(role: Role): string => {
|
||||
return role.name;
|
||||
}}
|
||||
.value=${(role: Role | undefined): string | undefined => {
|
||||
return role?.pk;
|
||||
}}
|
||||
>
|
||||
</ak-search-select>
|
||||
</ak-form-element-horizontal>
|
||||
${this.modelPermissions?.results
|
||||
.filter((perm) => {
|
||||
const [_app, model] = this.model?.split(".") || "";
|
||||
return perm.codename !== `add_${model}`;
|
||||
})
|
||||
.map((perm) => {
|
||||
return html`<ak-switch-input
|
||||
name="permissions.${perm.codename}"
|
||||
label=${perm.name}
|
||||
></ak-switch-input>`;
|
||||
})}
|
||||
</form>`;
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${msg("Role")} name="role">
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<Role[]> => {
|
||||
const args: RbacRolesListRequest = {
|
||||
ordering: "name",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const roles = await new RbacApi(DEFAULT_CONFIG).rbacRolesList(args);
|
||||
return roles.results;
|
||||
}}
|
||||
.renderElement=${(role: Role): string => {
|
||||
return role.name;
|
||||
}}
|
||||
.value=${(role: Role | undefined): string | undefined => {
|
||||
return role?.pk;
|
||||
}}
|
||||
>
|
||||
</ak-search-select>
|
||||
</ak-form-element-horizontal>
|
||||
${this.modelPermissions?.results
|
||||
.filter((perm) => {
|
||||
const [_app, model] = this.model?.split(".") || "";
|
||||
return perm.codename !== `add_${model}`;
|
||||
})
|
||||
.map((perm) => {
|
||||
return html`<ak-switch-input
|
||||
name="permissions.${perm.codename}"
|
||||
label=${perm.name}
|
||||
></ak-switch-input>`;
|
||||
})}
|
||||
</form>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ export class RoleAssignedObjectPermissionTable extends Table<RoleAssignedObjectP
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit">${msg("Assign")}</span>
|
||||
<span slot="header">${msg("Assign object permissions to role")}</span>
|
||||
<span slot="header">${msg("Assign permission to role")}</span>
|
||||
<ak-rbac-role-object-permission-form
|
||||
model=${ifDefined(this.model)}
|
||||
objectPk=${ifDefined(this.objectPk)}
|
||||
@@ -95,7 +95,7 @@ export class RoleAssignedObjectPermissionTable extends Table<RoleAssignedObjectP
|
||||
>
|
||||
</ak-rbac-role-object-permission-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Assign Object Permission")}
|
||||
${msg("Assign role permissions")}
|
||||
</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
@@ -135,9 +135,9 @@ export class RoleAssignedObjectPermissionTable extends Table<RoleAssignedObjectP
|
||||
const assignedToModel = item.modelPermissions.some(
|
||||
(uperm) => uperm.codename === perm.codename,
|
||||
);
|
||||
const assignedToObject = item.objectPermissions
|
||||
.filter((uperm) => uperm.objectPk === this.objectPk)
|
||||
.some((uperm) => uperm.codename === perm.codename);
|
||||
const assignedToObject = item.objectPermissions.some(
|
||||
(uperm) => uperm.codename === perm.codename,
|
||||
);
|
||||
|
||||
let tooltip: string | null = null;
|
||||
if (assignedToModel && assignedToObject) {
|
||||
|
||||
@@ -51,11 +51,6 @@ export class NavigationButtons extends WithSession(AKElement) {
|
||||
Styles,
|
||||
];
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this.refreshNotifications();
|
||||
}
|
||||
|
||||
protected async refreshNotifications(): Promise<void> {
|
||||
const { currentUser } = this;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ type Group<T> = [string, T[]];
|
||||
|
||||
export interface ISearchSelectBase<T> {
|
||||
blankable?: boolean;
|
||||
readOnly?: boolean;
|
||||
query?: string;
|
||||
objects?: T[];
|
||||
selectedObject: T | null;
|
||||
@@ -94,14 +93,6 @@ export abstract class SearchSelectBase<T>
|
||||
@property({ type: Boolean })
|
||||
public creatable?: boolean;
|
||||
|
||||
/**
|
||||
* Prevent user interaction while still rendering the current value.
|
||||
* @property
|
||||
* @attr
|
||||
*/
|
||||
@property({ type: Boolean, attribute: "readonly" })
|
||||
public readOnly = false;
|
||||
|
||||
/**
|
||||
* An initial string to filter the search contents,
|
||||
* and the value of the input which further serves to restrict the search.
|
||||
@@ -263,8 +254,6 @@ export abstract class SearchSelectBase<T>
|
||||
}
|
||||
|
||||
#searchListener = (event: InputEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
const value = (event.target as SearchSelectView).rawValue;
|
||||
|
||||
if (!value) {
|
||||
@@ -288,8 +277,6 @@ export abstract class SearchSelectBase<T>
|
||||
};
|
||||
|
||||
private onSelect(event: InputEvent) {
|
||||
if (this.readOnly) return;
|
||||
|
||||
const value = (event.target as SearchSelectView).value;
|
||||
|
||||
if (!value) {
|
||||
@@ -394,7 +381,6 @@ export abstract class SearchSelectBase<T>
|
||||
.options=${options}
|
||||
value=${ifPresent(value)}
|
||||
?blankable=${this.blankable}
|
||||
?readonly=${this.readOnly}
|
||||
label=${ifPresent(this.label)}
|
||||
name=${ifPresent(this.name)}
|
||||
placeholder=${ifPresent(this.placeholder)}
|
||||
|
||||
@@ -24,7 +24,6 @@ export interface ISearchSelectView {
|
||||
value?: string;
|
||||
open: boolean;
|
||||
blankable: boolean;
|
||||
readOnly: boolean;
|
||||
caseSensitive: boolean;
|
||||
name?: string;
|
||||
placeholder: string;
|
||||
@@ -127,14 +126,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
@property({ type: Boolean })
|
||||
public blankable = false;
|
||||
|
||||
/**
|
||||
* Prevents user interaction while showing the current value.
|
||||
*
|
||||
* @attr
|
||||
*/
|
||||
@property({ type: Boolean, attribute: "readonly" })
|
||||
public readOnly = false;
|
||||
|
||||
/**
|
||||
* If not managed, make the matcher case-sensitive during interaction. If managed,
|
||||
* the manager must handle this.
|
||||
@@ -257,8 +248,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
//#region Event Listeners
|
||||
|
||||
#clickListener = (_ev: Event) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
this.open = !this.open;
|
||||
this.#inputRef.value?.focus();
|
||||
};
|
||||
@@ -274,8 +263,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
}
|
||||
|
||||
#searchKeyupListener = (event: KeyboardEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
if (event.key === "Escape") {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
@@ -290,8 +277,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
};
|
||||
|
||||
#searchKeydownListener = (event: KeyboardEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
if (!this.open) return;
|
||||
|
||||
switch (event.key) {
|
||||
@@ -354,8 +339,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
}
|
||||
|
||||
#inputListener = (_ev: InputEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
if (!this.managed) {
|
||||
this.findValueForInput();
|
||||
this.requestUpdate();
|
||||
@@ -373,8 +356,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
};
|
||||
|
||||
#listKeydownListener = (event: KeyboardEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
if (event.key === "Tab" && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -383,8 +364,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
};
|
||||
|
||||
#changeListener = (event: InputEvent) => {
|
||||
if (this.readOnly) return;
|
||||
|
||||
if (!event.target) {
|
||||
return;
|
||||
}
|
||||
@@ -462,7 +441,6 @@ export class SearchSelectView extends AKElement implements ISearchSelectView {
|
||||
@keyup=${this.#searchKeyupListener}
|
||||
@keydown=${this.#searchKeydownListener}
|
||||
value=${this.displayValue}
|
||||
?readonly=${this.readOnly}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4183,6 +4183,9 @@ neprojde, když jedna nebo obě z vybraných možností jsou rovny nebo nad prah
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4281,6 +4284,12 @@ neprojde, když jedna nebo obě z vybraných možností jsou rovny nebo nad prah
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7884,6 +7893,10 @@ neprojde, když jedna nebo obě z vybraných možností jsou rovny nebo nad prah
|
||||
<source>Send notification to event user</source>
|
||||
<target>Zasílat oznámení původci události</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Pokud je povoleno, oznámení se kromě uživatelů ve skupině výše odešle také původci události. Uživatel, který událost vyvolal, je vždy prvním příjemcem; pokud má být oznámení doručeno pouze jednou, je třeba v transportu notifikací zapnout volbu ‘Poslat jednou’.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Transporty</target>
|
||||
@@ -8073,6 +8086,10 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
|
||||
<source>Local</source>
|
||||
<target>Místní</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Pokud je povoleno, použije se místní připojení. Vyžaduje Docker socket/Kubernetes integraci.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9541,6 +9558,9 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9673,6 +9693,9 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9778,6 +9801,9 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9874,53 +9900,6 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4214,6 +4214,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4312,6 +4315,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7918,6 +7927,10 @@ Beim Erstellen eines festen Auswahlfelds aktiviere „Als Ausdruck interpretiere
|
||||
<source>Send notification to event user</source>
|
||||
<target>Benachrichtigung an Ereignisbenutzer senden</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Wenn aktiviert, wird zusätzlich zu den Benutzern der oben ausgewählten Gruppe auch der Benutzer benachrichtigt, der das Ereignis ausgelöst hat. Der Ereignisbenutzer wird immer als erster benachrichtigt. Um eine Benachrichtigung nur an den Ereignisbenutzer zu senden, aktiviere „Einmal senden“ im Benachrichtigungstransport.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Zustellungsarten</target>
|
||||
@@ -8107,6 +8120,10 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
|
||||
<source>Local</source>
|
||||
<target>Lokal</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Nutze, wenn aktiviert, die lokale Verbindung. Benötigt Docker socket/Kubernetes Integration.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9581,6 +9598,9 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9713,6 +9733,9 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9818,6 +9841,9 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9914,53 +9940,6 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3220,6 +3220,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -3316,6 +3319,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -6076,6 +6085,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
</trans-unit>
|
||||
@@ -6215,6 +6227,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="se9b1fec72ffd8f48">
|
||||
<source>Local</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
</trans-unit>
|
||||
@@ -7374,6 +7389,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -7506,6 +7524,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -7611,6 +7632,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -7707,53 +7731,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4151,6 +4151,9 @@ no se aprueba cuando una o ambas de las opciones seleccionadas son iguales o sup
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4249,6 +4252,12 @@ no se aprueba cuando una o ambas de las opciones seleccionadas son iguales o sup
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7846,6 +7855,10 @@ El valor de este campo se compara con el atributo de pertenencia del usuario.</t
|
||||
<source>Send notification to event user</source>
|
||||
<target>Enviar notificación al usuario del evento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Cuando está habilitado, se enviará una notificación al usuario que desencadenó el evento, además de a cualquier usuario en el grupo mencionado anteriormente. El usuario del evento siempre será el primer usuario; para enviar una notificación solo a este usuario, active 'Enviar una vez' en el transporte de notificaciones.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Medios</target>
|
||||
@@ -8035,6 +8048,10 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
|
||||
<source>Local</source>
|
||||
<target>Local</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Si está habilitada, use la conexión local. Se requiere la integración de Docker Socket/Kubernetes.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>URL de Docker</target>
|
||||
@@ -9501,6 +9518,9 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9633,6 +9653,9 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9738,6 +9761,9 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9834,53 +9860,6 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4293,6 +4293,9 @@ läpäisy estyy kun jompi kumpi tai molemmat vaihtoehdot ylittävät raja-arvon.
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4391,6 +4394,12 @@ läpäisy estyy kun jompi kumpi tai molemmat vaihtoehdot ylittävät raja-arvon.
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -8049,6 +8058,10 @@ läpäisy estyy kun jompi kumpi tai molemmat vaihtoehdot ylittävät raja-arvon.
|
||||
<source>Send notification to event user</source>
|
||||
<target>Lähetä notifikaatiot tapahtuman käyttäjälle</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Kun tämä on käytössä, notifikaatio lähetetään sille käyttäjälle, joka laukaisi tapahtuman, niiden käyttäjien lisäksi, jotka ovat yllä olevan ryhmän jäseniä. Tapahtuman käyttäjä on aina ensimmäinen käyttäjä. Lähettääksesi notifikaation vain tapahtuman käyttäjälle, valitse 'Lähetä kerran' notifikaation väylän asetuksissa.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Väylät</target>
|
||||
@@ -8238,6 +8251,10 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
|
||||
<source>Local</source>
|
||||
<target>Paikallinen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Jos käytössä, käytä paikallista yhteyttä. Pakollinen Docker socket/Kubernetes-integraatio.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9764,6 +9781,9 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9896,6 +9916,9 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -10001,6 +10024,9 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -10097,53 +10123,6 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4282,6 +4282,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4380,6 +4383,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -8039,6 +8048,10 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<source>Send notification to event user</source>
|
||||
<target>Envoyer la notification à l'utilisateur associé à l'événement</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Lorsque cette option est activée, une notification sera envoyée à l'utilisateur qui a déclenché l'événement en plus des utilisateurs du groupe ci-dessus. L'utilisateur associé à l'événement sera toujours le premier utilisateur. Pour envoyer une notification uniquement à l'utilisateur de l'événement, activez l'option "Envoyer une seule fois" dans le transport de notification.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Transports</target>
|
||||
@@ -8228,6 +8241,10 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<source>Local</source>
|
||||
<target>Local</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Si activé, utiliser la connexion locale. Intégration Docker socket/Kubernetes requise.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>URL Docker</target>
|
||||
@@ -9749,6 +9766,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9881,6 +9901,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9986,6 +10009,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -10082,53 +10108,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4110,6 +4110,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4208,6 +4211,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7801,6 +7810,10 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<source>Send notification to event user</source>
|
||||
<target>Invia notifica all'utente dell'evento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Se abilitata, la notifica verrà inviata all'utente che ha attivato l'evento, oltre a tutti gli utenti del gruppo sopra indicato. L'utente dell'evento sarà sempre il primo a inviare una notifica solo all'utente dell'evento che ha abilitato "Invia una volta" nel trasporto delle notifiche.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Trasporti</target>
|
||||
@@ -7990,6 +8003,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>Locale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Se abilitato, utilizzare la connessione locale. Integrazione Docker Cocket Docker/Kubernetes.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9449,6 +9466,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9581,6 +9601,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9686,6 +9709,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9782,53 +9808,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4284,6 +4284,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4382,6 +4385,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -8037,6 +8046,11 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<source>Send notification to event user</source>
|
||||
<target>イベントユーザーに通知を送信</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>有効になると、イベントをトリガーしたユーザーと上記のグループ内のユーザーに通知が送信されます。イベントユーザーは常に最初のユーザーになります。イベントユーザーにのみ通知を送信するには、通知トランスポートで「1
|
||||
回だけ送信」を有効にします。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>トランスポート</target>
|
||||
@@ -8222,6 +8236,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>ローカル</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>有効にすると、ローカル接続を使用します。Docker ソケット/Kubernetes 統合が必要です。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9743,6 +9761,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9875,6 +9896,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9980,6 +10004,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -10076,53 +10103,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3951,6 +3951,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4049,6 +4052,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7499,6 +7508,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>전송</target>
|
||||
@@ -7680,6 +7692,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>로컬</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>활성화된 경우, 로컬 연결을 사용합니다. 도커/쿠버네티스 통합에 필수적입니다.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>도커 URL</target>
|
||||
@@ -9074,6 +9090,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9206,6 +9225,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9311,6 +9333,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9407,53 +9432,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3789,6 +3789,9 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -3887,6 +3890,12 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7217,6 +7226,9 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Transporten</target>
|
||||
@@ -7393,6 +7405,10 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<source>Local</source>
|
||||
<target>Lokaal</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Indien ingeschakeld, gebruik de lokale verbinding. Vereist Docker-socket/Kubernetes-integratie.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker-URL</target>
|
||||
@@ -8722,6 +8738,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -8854,6 +8873,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -8959,6 +8981,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9055,53 +9080,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3966,6 +3966,9 @@ nie przechodzi, gdy jedna lub obie wybrane opcje są równe lub wyższe od progu
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4064,6 +4067,12 @@ nie przechodzi, gdy jedna lub obie wybrane opcje są równe lub wyższe od progu
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7521,6 +7530,9 @@ w toku, tworzony jest nowy użytkownik i zapisywane są do niego dane.</target>
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Transporty</target>
|
||||
@@ -7707,6 +7719,10 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<source>Local</source>
|
||||
<target>Lokalny</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Jeśli jest włączone, użyj połączenia lokalnego. Wymagane socket Docker/Integracja Kubernetes.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>URL Dockera</target>
|
||||
@@ -9104,6 +9120,9 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9236,6 +9255,9 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9341,6 +9363,9 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9437,53 +9462,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4287,6 +4287,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4385,6 +4388,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -8034,6 +8043,10 @@ retorne uma lista para fornecer várias opções padrão.</target>
|
||||
<source>Send notification to event user</source>
|
||||
<target>Enviar notificação para o usuário do evento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>Quando ativado, a notificação será enviada ao usuário que acionou o evento, além de quaisquer usuários no grupo acima. O usuário do evento será sempre o primeiro usuário; para enviar uma notificação apenas ao usuário do evento, ative 'Enviar uma vez' no transporte de notificação.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Transportes</target>
|
||||
@@ -8220,6 +8233,10 @@ As vinculações a grupos/usuários são verificadas em relação ao usuário do
|
||||
<source>Local</source>
|
||||
<target>Local</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Se ativado, use a conexão local. Requer integração com Docker socket/Kubernetes.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>URL do Docker</target>
|
||||
@@ -9732,6 +9749,9 @@ por exemplo: <x id="0" equiv-text="<code>"/>oci://registry.domain.tld/path
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9864,6 +9884,9 @@ por exemplo: <x id="0" equiv-text="<code>"/>oci://registry.domain.tld/path
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9969,6 +9992,9 @@ por exemplo: <x id="0" equiv-text="<code>"/>oci://registry.domain.tld/path
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -10065,53 +10091,6 @@ por exemplo: <x id="0" equiv-text="<code>"/>oci://registry.domain.tld/path
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4004,6 +4004,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4102,6 +4105,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7579,6 +7588,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Поставщики</target>
|
||||
@@ -7765,6 +7777,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>Местный</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Если включено, используется локальное соединение. Требует Docker сокет/Kubernetes интеграции.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>URL-адрес Docker</target>
|
||||
@@ -9192,6 +9208,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9324,6 +9343,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9429,6 +9451,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9525,53 +9550,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3983,6 +3983,9 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4081,6 +4084,12 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7569,6 +7578,9 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>Aktarıcılar</target>
|
||||
@@ -7754,6 +7766,10 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<source>Local</source>
|
||||
<target>Yerel</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>Etkinleştirilirse, yerel bağlantıyı kullanın. Gerekli Docker soketi/Kubernetes Entegrasyonu.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL'si</target>
|
||||
@@ -9170,6 +9186,9 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9302,6 +9321,9 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9407,6 +9429,9 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9503,53 +9528,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -4250,6 +4250,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -4348,6 +4351,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -8001,6 +8010,10 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<source>Send notification to event user</source>
|
||||
<target>发送通知给事件用户</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
<target>启用时,通知不仅会发送给触发事件的用户,还会发送到组中的任何用户。事件用户将总是第一个用户,要只向事件用户发送通知,则需要在通知传输中启用“发送一次”。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>传输</target>
|
||||
@@ -8190,6 +8203,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>本地</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>如果启用,请使用本地连接。需要 Docker Socket/Kubernetes 集成。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker URL</target>
|
||||
@@ -9704,6 +9721,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -9836,6 +9856,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9941,6 +9964,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -10037,53 +10063,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@@ -3821,6 +3821,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="sf96a86df0756bc7b">
|
||||
<source>Afterwards, select the enrollment token you want to use:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13b4cf044a01dde2">
|
||||
<source>Then download the configuration to deploy the authentik Agent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s12f523a52b843ea2">
|
||||
<source>macOS</source>
|
||||
</trans-unit>
|
||||
@@ -3919,6 +3922,12 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s94a50f1495fb5ccd">
|
||||
<source>Disk encryption</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s76ea179414f2b2a5">
|
||||
<source>Disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s25e7a078391a3ec3">
|
||||
<source>Disk usage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s416211a967a6db4e">
|
||||
<source>Users / Groups</source>
|
||||
</trans-unit>
|
||||
@@ -7283,6 +7292,9 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
<trans-unit id="s47966b2a708694e2">
|
||||
<source>Send notification to event user</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sd30f00ff2135589c">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sffa171e11d4ae513">
|
||||
<source>Transports</source>
|
||||
<target>通道</target>
|
||||
@@ -7458,6 +7470,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Local</source>
|
||||
<target>本機端連線</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc1231049879b8d33">
|
||||
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
|
||||
<target>啟用時,請使用本機連線。需要整合 docker / Kubernetes 的 socket。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s13de04774ff0f210">
|
||||
<source>Docker URL</source>
|
||||
<target>Docker 網址</target>
|
||||
@@ -8785,6 +8801,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s6df8326edea3b23d">
|
||||
<source>If no device was provided, this stage will stop flow execution.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s506c7d2e87f6770e">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, and underscores</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s3a3d5b2575cd32ea">
|
||||
<source>File uploaded successfully</source>
|
||||
</trans-unit>
|
||||
@@ -8917,6 +8936,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc47f8ab6162bb2bb">
|
||||
<source>Outpost configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s184c3b30bebb2dd8">
|
||||
<source>Assign role permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s11a2ac9f2bd811d8">
|
||||
<source>Delete Object Permission</source>
|
||||
</trans-unit>
|
||||
@@ -9022,6 +9044,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7dcfe418b8d601f6">
|
||||
<source>Flags allow you to enable new functionality and behaviour in authentik early.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbaeb8266aac13639">
|
||||
<source>Buffer PolicyAccessVew requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se20d0be2cece3841">
|
||||
<source>When enabled, parallel requests for application authorization will be buffered instead of conflicting with other flows.</source>
|
||||
</trans-unit>
|
||||
@@ -9118,53 +9143,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s567c5a6e42cc5036">
|
||||
<source>Maximum page size for API requests.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sed1058bca1c065f7">
|
||||
<source>When enabled, notification will be sent to the user that triggered the event in addition to any users in the group above. The event user will always be the first user, to send a notification only to the event user enabled 'Send once' in the notification transport. If no group is selected and 'Send notification to event user' is disabled the rule is disabled. </source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s9864bd5cd7bb4bd0">
|
||||
<source>Local connection</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4a3f19ff6e510c37">
|
||||
<source>Requires Docker socket/Kubernetes Integration.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s46a03121a2c260ea">
|
||||
<source>Buffer PolicyAccessView requests</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s361e9d929ee925e6">
|
||||
<source>Assign Object Permission</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s5f6ad947b4824e40">
|
||||
<source>Next, download the configuration to deploy the authentik Agent via MDM</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s523337424b694d5c">
|
||||
<source>Device Access Group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7642bf28cf8f476c">
|
||||
<source>Select a device access group to be added to upon enrollment.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="h30bbf18fbf87fa57">
|
||||
<source>To create a data export, navigate to
|
||||
<x id="0" equiv-text="<a href="#/identity/users">"/>Directory > Users<x id="1" equiv-text="</a>"/> or to
|
||||
<x id="2" equiv-text="<a href="#/events/log">"/>Events > Logs<x id="3" equiv-text="</a>"/>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s813faec5ff1d32d1">
|
||||
<source>Filename can only contain letters, numbers, dots, hyphens, underscores, and slashes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s54af3ec70642782c">
|
||||
<source>Choose the object permissions that you want the selected role to have on this object. These object permissions are in addition to any global permissions already within the role.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb3be65525dd1f92c">
|
||||
<source>Assign object permissions to role</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sbcd108b66363075c">
|
||||
<source>Device access group</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s325acae04cdcac57">
|
||||
<source>Primary disk size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4a957846c89fca1">
|
||||
<source>Primary disk usage</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user