Compare commits

..

32 Commits

Author SHA1 Message Date
66a4970014 release: 2024.10.2 2024-11-14 17:05:40 +01:00
7ab9300761 website/docs: 2024.10.2 release notes (cherry-pick #12025) (#12026)
website/docs: 2024.10.2 release notes (#12025)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-14 17:00:32 +01:00
a2eccd5022 core: use versioned_script for path only (cherry-pick #12003) (#12023)
core: use versioned_script for path only (#12003)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-14 14:03:03 +01:00
31aeaa247f providers/oauth2: fix manual device code entry (cherry-pick #12017) (#12019)
providers/oauth2: fix manual device code entry (#12017)

* providers/oauth2: fix manual device code entry



* make code input a char field to prevent leading 0s from being cut off



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-13 21:59:10 +01:00
f49008bbb6 crypto: validate that generated certificate's name is unique (cherry-pick #12015) (#12016)
crypto: validate that generated certificate's name is unique (#12015)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-13 17:05:59 +01:00
feb13c8ee5 providers/proxy: fix Issuer when AUTHENTIK_HOST_BROWSER is set (cherry-pick #11968) (#12005)
providers/proxy: fix Issuer when AUTHENTIK_HOST_BROWSER is set (#11968)

correctly use host_browser's hostname as host header for token requests to ensure Issuer is identical

Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-13 00:59:10 +01:00
d5ef831718 web: bump API Client version (#11992)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	web/package-lock.json
#	web/package.json
2024-11-11 14:30:24 +01:00
64676819ec blueprints: add default Password policy (cherry-pick #11793) (#11993)
blueprints: add default Password policy (#11793)

* add password policy to default password change flow

This change complies with the minimal compositional requirements by
NIST SP 800-63 Digital Identity Guidelines. See
https://pages.nist.gov/800-63-4/sp800-63b.html#password

More work is needed to comply with other parts of the Guidelines,
specifically

> If the chosen password is found on the blocklist, the CSP or verifier
> [...] SHALL provide the reason for rejection.

and

> Verifiers SHALL offer guidance to the subscriber to assist the user in
> choosing a strong password. This is particularly important following
> the rejection of a password on the blocklist as it discourages trivial
> modification of listed weak passwords.

* add docs for default Password policy

* remove HIBP from default Password policy

* add zxcvbn to default Password policy

* add fallback password error message to password policy, fix validation policy



* reword docs




* add HIBP caveat




* separate policy into separate blueprint



* use password policy for oobe flow



* kiss



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2024-11-11 13:54:44 +01:00
7ed268fef4 stages/captcha: Run interactive captcha in Frame (cherry-pick #11857) (#11991)
stages/captcha: Run interactive captcha in Frame (#11857)

* initial turnstile frame



* add interactive flag



* add interactive support for all



* fix missing migration



* don't hide in identification stage if interactive



* fixup



* require less hacky css



* update docs



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-11 13:31:01 +01:00
f6526d1be9 stages/password: use recovery flow from brand (cherry-pick #11953) (#11969)
stages/password: use recovery flow from brand (#11953)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-08 16:56:16 +01:00
12f8b4566b website/docs: fix slug matching redirect URI causing broken refresh (cherry-pick #11950) (#11954)
website/docs: fix slug matching redirect URI causing broken refresh (#11950)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-07 19:26:49 +01:00
665de8ef22 release: 2024.10.1 2024-11-05 18:06:32 +01:00
9eaa723bf8 website/docs: 2024.10.1 Release Notes (cherry-pick #11926) (#11928)
website/docs: `2024.10.1` Release Notes (#11926)

* fix API Changes in `2024.10` changelog

* add `2024.10.1` API Changes to changelog

* add changes in `2024.10.1` to changelog

* change `details` to `h3` in changelog

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-11-05 18:05:00 +01:00
b2ca9c8cbc website: remove RC disclaimer for version 2024.10 (cherry-pick #11871) (#11920)
website: remove RC disclaimer for version 2024.10 (#11871)

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-11-05 12:13:11 +01:00
7927392100 website/docs: add info about invalidation flow, default flows in general (cherry-pick #11800) (#11921)
website/docs: add info about invalidation flow, default flows in general (#11800)

* restructure

* tweak

* fix header

* added more definitions

* jens excellent idea

* restructure the Layouts content

* tweaks

* links fix

* links still

* fighting links and cache

* argh links

* ditto

* remove link

* anothe link

* Jens' edit

* listed default flows set by brand

* add links back

* tweaks

* used import for list

* tweak

* rewrite some stuff



* format



* mangled rebase, fixed

* bump

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2024-11-05 12:12:59 +01:00
d8d07e32cb website: fix docs redirect (cherry-pick #11873) (#11922)
website: fix docs redirect (#11873)

fix docs redirect

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-11-05 12:12:46 +01:00
f7c5d329eb website/docs: fix release notes to say Federation (cherry-pick #11889) (#11923)
website/docs: fix release notes to say Federation (#11889)

* fix Federation

* typo

* added back should

* slooooow down

---------

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.com>
2024-11-05 12:12:27 +01:00
92dec32547 enterprise/rac: fix API Schema for invalidation_flow (cherry-pick #11907) (#11908)
enterprise/rac: fix API Schema for invalidation_flow (#11907)

* enterprise/rac: fix API Schema for invalidation_flow



* fix tests



* add tests



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-11-04 20:42:41 +01:00
510feccd31 core: add None check to a device's extra_description (cherry-pick #11904) (#11906)
core: add `None` check to a device's `extra_description` (#11904)

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-11-04 18:12:34 +01:00
364a9a1f02 web: fix missing status code on failed build (#11903)
* fix missing status code on failed build

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix locale

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	web/xliff/tr.xlf
2024-11-04 18:06:22 +01:00
40cbb7567b providers/oauth2: fix size limited index for tokens (cherry-pick #11879) (#11905)
providers/oauth2: fix size limited index for tokens (#11879)

* providers/oauth2: fix size limited index for tokens

I preserved the migrations as comments so the index IDs and migration
IDs remain searchable without accessing git history.

* rename migration file to more descriptive

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-11-04 18:05:55 +01:00
8ad0f63994 website: update supported versions (cherry-pick #11841) (#11872)
website: update supported versions (#11841)

update supported versions

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2024-10-31 12:59:54 +01:00
6ce33ab912 root: bumpversion 2024.10 (#11865)
release: 2024.10.0
2024-10-30 22:45:48 +01:00
d96b577abd web/admin: fix code-based MFA toggle not working in wizard (cherry-pick #11854) (#11855)
web/admin: fix code-based MFA toggle not working in wizard (#11854)

closes #11834

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-10-29 20:19:54 +01:00
8c547589f6 sources/kerberos: add kiprop to ignored system principals (cherry-pick #11852) (#11853)
sources/kerberos: add kiprop to ignored system principals (#11852)

Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-10-29 17:31:32 +01:00
3775e5b84f website: 2024.10 Release Notes (cherry-pick #11839) (#11840)
website: 2024.10 Release Notes (#11839)

* generate diffs and changelog

* add 2024.10 release notes

* reorder release note highlights

* lint website

* reorder release note new features

* reword Kerberos




* extend JWE description




---------

Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-10-28 17:27:59 +01:00
fa30339f65 website/docs: remove � (cherry-pick #11823) (#11835)
website/docs: remove � (#11823)

remove 

Signed-off-by: Tobias <5702338+T0biii@users.noreply.github.com>
Co-authored-by: Tobias <5702338+T0biii@users.noreply.github.com>
2024-10-28 13:21:02 +01:00
e825eda106 website/docs: Update social-logins github (cherry-pick #11822) (#11836)
website/docs: Update social-logins github (#11822)

Update index.md

Signed-off-by: Tobias <5702338+T0biii@users.noreply.github.com>
Co-authored-by: Tobias <5702338+T0biii@users.noreply.github.com>
2024-10-28 13:20:38 +01:00
246cae3dfa lifecycle: fix kdc5-config missing (cherry-pick #11826) (#11829)
lifecycle: fix kdc5-config missing (#11826)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-10-28 01:15:50 +01:00
6cfd2bd1af website/docs: update preview status of different features (cherry-pick #11817) (#11818)
website/docs: update preview status of different features (#11817)

* remove preview from RAC



* add preview page instead of info box



* remove preview from rbac



* add preview to gdtc



* add preview to kerberos source



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-10-25 21:42:45 +02:00
f0e4f93fe6 lifecycle: fix missing krb5 deps for full testing in image (cherry-pick #11815) (#11816)
lifecycle: fix missing krb5 deps for full testing in image (#11815)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-10-25 18:46:55 +02:00
434aa57ba7 release: 2024.10.0-rc1 2024-10-25 17:26:39 +02:00
95 changed files with 2383 additions and 10375 deletions

View File

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 2024.10.0 current_version = 2024.10.2
tag = True tag = True
commit = True commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -2,7 +2,7 @@
from os import environ from os import environ
__version__ = "2024.10.0" __version__ = "2024.10.2"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -7,7 +7,7 @@ API Browser - {{ brand.branding_title }}
{% endblock %} {% endblock %}
{% block head %} {% block head %}
{% versioned_script "dist/standalone/api-browser/index-%v.js" %} <script src="{% versioned_script 'dist/standalone/api-browser/index-%v.js' %}" type="module"></script>
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)"> <meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
{% endblock %} {% endblock %}

View File

@ -27,7 +27,8 @@ def blueprint_tester(file_name: Path) -> Callable:
base = Path("blueprints/") base = Path("blueprints/")
rel_path = Path(file_name).relative_to(base) rel_path = Path(file_name).relative_to(base)
importer = Importer.from_string(BlueprintInstance(path=str(rel_path)).retrieve()) importer = Importer.from_string(BlueprintInstance(path=str(rel_path)).retrieve())
self.assertTrue(importer.validate()[0]) validation, logs = importer.validate()
self.assertTrue(validation, logs)
self.assertTrue(importer.apply()) self.assertTrue(importer.apply())
return tester return tester

View File

@ -1,5 +1,6 @@
"""Authenticator Devices API Views""" """Authenticator Devices API Views"""
from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework.fields import ( from rest_framework.fields import (
@ -40,7 +41,11 @@ class DeviceSerializer(MetaNameSerializer):
def get_extra_description(self, instance: Device) -> str: def get_extra_description(self, instance: Device) -> str:
"""Get extra description""" """Get extra description"""
if isinstance(instance, WebAuthnDevice): if isinstance(instance, WebAuthnDevice):
return instance.device_type.description return (
instance.device_type.description
if instance.device_type
else _("Extra description not available")
)
if isinstance(instance, EndpointDevice): if isinstance(instance, EndpointDevice):
return instance.data.get("deviceSignals", {}).get("deviceModel") return instance.data.get("deviceSignals", {}).get("deviceModel")
return "" return ""

View File

@ -15,8 +15,8 @@
{% endblock %} {% endblock %}
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject> <link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
{% versioned_script "dist/poly-%v.js" %} <script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
{% versioned_script "dist/standalone/loading/index-%v.js" %} <script src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}" type="module"></script>
{% block head %} {% block head %}
{% endblock %} {% endblock %}
<meta name="sentry-trace" content="{{ sentry_trace }}" /> <meta name="sentry-trace" content="{{ sentry_trace }}" />

View File

@ -3,7 +3,7 @@
{% load authentik_core %} {% load authentik_core %}
{% block head %} {% block head %}
{% versioned_script "dist/admin/AdminInterface-%v.js" %} <script src="{% versioned_script 'dist/admin/AdminInterface-%v.js' %}" type="module"></script>
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)"> <meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
{% include "base/header_js.html" %} {% include "base/header_js.html" %}

View File

@ -3,7 +3,7 @@
{% load authentik_core %} {% load authentik_core %}
{% block head %} {% block head %}
{% versioned_script "dist/user/UserInterface-%v.js" %} <script src="{% versioned_script 'dist/user/UserInterface-%v.js' %}" type="module"></script>
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)"> <meta name="theme-color" content="#1c1e21" media="(prefers-color-scheme: dark)">
{% include "base/header_js.html" %} {% include "base/header_js.html" %}

View File

@ -2,7 +2,6 @@
from django import template from django import template
from django.templatetags.static import static as static_loader from django.templatetags.static import static as static_loader
from django.utils.safestring import mark_safe
from authentik import get_full_version from authentik import get_full_version
@ -12,10 +11,4 @@ register = template.Library()
@register.simple_tag() @register.simple_tag()
def versioned_script(path: str) -> str: def versioned_script(path: str) -> str:
"""Wrapper around {% static %} tag that supports setting the version""" """Wrapper around {% static %} tag that supports setting the version"""
returned_lines = [ return static_loader(path.replace("%v", get_full_version()))
(
f'<script src="{static_loader(path.replace("%v", get_full_version()))}'
'" type="module"></script>'
),
]
return mark_safe("".join(returned_lines)) # nosec

View File

@ -24,6 +24,7 @@ from rest_framework.fields import (
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.validators import UniqueValidator
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -181,7 +182,10 @@ class CertificateDataSerializer(PassiveSerializer):
class CertificateGenerationSerializer(PassiveSerializer): class CertificateGenerationSerializer(PassiveSerializer):
"""Certificate generation parameters""" """Certificate generation parameters"""
common_name = CharField() common_name = CharField(
validators=[UniqueValidator(queryset=CertificateKeyPair.objects.all())],
source="name",
)
subject_alt_name = CharField(required=False, allow_blank=True, label=_("Subject-alt name")) subject_alt_name = CharField(required=False, allow_blank=True, label=_("Subject-alt name"))
validity_days = IntegerField(initial=365) validity_days = IntegerField(initial=365)
alg = ChoiceField(default=PrivateKeyAlg.RSA, choices=PrivateKeyAlg.choices) alg = ChoiceField(default=PrivateKeyAlg.RSA, choices=PrivateKeyAlg.choices)
@ -242,11 +246,10 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
def generate(self, request: Request) -> Response: def generate(self, request: Request) -> Response:
"""Generate a new, self-signed certificate-key pair""" """Generate a new, self-signed certificate-key pair"""
data = CertificateGenerationSerializer(data=request.data) data = CertificateGenerationSerializer(data=request.data)
if not data.is_valid(): data.is_valid(raise_exception=True)
return Response(data.errors, status=400)
raw_san = data.validated_data.get("subject_alt_name", "") raw_san = data.validated_data.get("subject_alt_name", "")
sans = raw_san.split(",") if raw_san != "" else [] sans = raw_san.split(",") if raw_san != "" else []
builder = CertificateBuilder(data.validated_data["common_name"]) builder = CertificateBuilder(data.validated_data["name"])
builder.alg = data.validated_data["alg"] builder.alg = data.validated_data["alg"]
builder.build( builder.build(
subject_alt_names=sans, subject_alt_names=sans,

View File

@ -89,6 +89,17 @@ class TestCrypto(APITestCase):
self.assertIsInstance(ext[1], DNSName) self.assertIsInstance(ext[1], DNSName)
self.assertEqual(ext[1].value, "baz") self.assertEqual(ext[1].value, "baz")
def test_builder_api_duplicate(self):
"""Test Builder (via API)"""
cert = create_test_cert()
self.client.force_login(create_test_admin_user())
res = self.client.post(
reverse("authentik_api:certificatekeypair-generate"),
data={"common_name": cert.name, "subject_alt_name": "bar,baz", "validity_days": 3},
)
self.assertEqual(res.status_code, 400)
self.assertJSONEqual(res.content, {"common_name": ["This field must be unique."]})
def test_builder_api_empty_san(self): def test_builder_api_empty_san(self):
"""Test Builder (via API)""" """Test Builder (via API)"""
self.client.force_login(create_test_admin_user()) self.client.force_login(create_test_admin_user())

View File

@ -16,13 +16,28 @@ class RACProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
class Meta: class Meta:
model = RACProvider model = RACProvider
fields = ProviderSerializer.Meta.fields + [ fields = [
"pk",
"name",
"authentication_flow",
"authorization_flow",
"property_mappings",
"component",
"assigned_application_slug",
"assigned_application_name",
"assigned_backchannel_application_slug",
"assigned_backchannel_application_name",
"verbose_name",
"verbose_name_plural",
"meta_model_name",
"settings", "settings",
"outpost_set", "outpost_set",
"connection_expiry", "connection_expiry",
"delete_token_on_disconnect", "delete_token_on_disconnect",
] ]
extra_kwargs = ProviderSerializer.Meta.extra_kwargs extra_kwargs = {
"authorization_flow": {"required": True, "allow_null": False},
}
class RACProviderViewSet(UsedByMixin, ModelViewSet): class RACProviderViewSet(UsedByMixin, ModelViewSet):

View File

@ -3,7 +3,7 @@
{% load authentik_core %} {% load authentik_core %}
{% block head %} {% block head %}
{% versioned_script "dist/enterprise/rac/index-%v.js" %} <script src="{% versioned_script 'dist/enterprise/rac/index-%v.js' %}" type="module"></script>
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)"> <meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<link rel="icon" href="{{ tenant.branding_favicon }}"> <link rel="icon" href="{{ tenant.branding_favicon }}">

View File

@ -0,0 +1,46 @@
"""Test RAC Provider"""
from datetime import timedelta
from time import mktime
from unittest.mock import MagicMock, patch
from django.urls import reverse
from django.utils.timezone import now
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.enterprise.license import LicenseKey
from authentik.enterprise.models import License
from authentik.lib.generators import generate_id
class TestAPI(APITestCase):
"""Test Provider API"""
def setUp(self) -> None:
self.user = create_test_admin_user()
@patch(
"authentik.enterprise.license.LicenseKey.validate",
MagicMock(
return_value=LicenseKey(
aud="",
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
name=generate_id(),
internal_users=100,
external_users=100,
)
),
)
def test_create(self):
"""Test creation of RAC Provider"""
License.objects.create(key=generate_id())
self.client.force_login(self.user)
response = self.client.post(
reverse("authentik_api:racprovider-list"),
data={
"name": generate_id(),
"authorization_flow": create_test_flow().pk,
},
)
self.assertEqual(response.status_code, 201)

View File

@ -68,7 +68,6 @@ class TestEndpointsAPI(APITestCase):
"name": self.provider.name, "name": self.provider.name,
"authentication_flow": None, "authentication_flow": None,
"authorization_flow": None, "authorization_flow": None,
"invalidation_flow": None,
"property_mappings": [], "property_mappings": [],
"connection_expiry": "hours=8", "connection_expiry": "hours=8",
"delete_token_on_disconnect": False, "delete_token_on_disconnect": False,
@ -121,7 +120,6 @@ class TestEndpointsAPI(APITestCase):
"name": self.provider.name, "name": self.provider.name,
"authentication_flow": None, "authentication_flow": None,
"authorization_flow": None, "authorization_flow": None,
"invalidation_flow": None,
"property_mappings": [], "property_mappings": [],
"component": "ak-provider-rac-form", "component": "ak-provider-rac-form",
"assigned_application_slug": self.app.slug, "assigned_application_slug": self.app.slug,
@ -151,7 +149,6 @@ class TestEndpointsAPI(APITestCase):
"name": self.provider.name, "name": self.provider.name,
"authentication_flow": None, "authentication_flow": None,
"authorization_flow": None, "authorization_flow": None,
"invalidation_flow": None,
"property_mappings": [], "property_mappings": [],
"component": "ak-provider-rac-form", "component": "ak-provider-rac-form",
"assigned_application_slug": self.app.slug, "assigned_application_slug": self.app.slug,

View File

@ -18,7 +18,7 @@ window.authentik.flow = {
{% endblock %} {% endblock %}
{% block head %} {% block head %}
{% versioned_script "dist/flow/FlowInterface-%v.js" %} <script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
<style> <style>
:root { :root {
--ak-flow-background: url("{{ flow.background_url }}"); --ak-flow-background: url("{{ flow.background_url }}");

View File

@ -89,6 +89,10 @@ class PasswordPolicy(Policy):
def passes_static(self, password: str, request: PolicyRequest) -> PolicyResult: def passes_static(self, password: str, request: PolicyRequest) -> PolicyResult:
"""Check static rules""" """Check static rules"""
error_message = self.error_message
if error_message == "":
error_message = _("Invalid password.")
if len(password) < self.length_min: if len(password) < self.length_min:
LOGGER.debug("password failed", check="static", reason="length") LOGGER.debug("password failed", check="static", reason="length")
return PolicyResult(False, self.error_message) return PolicyResult(False, self.error_message)

View File

@ -11,13 +11,16 @@ class Migration(migrations.Migration):
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ # Original preserved
migrations.AddIndex( # See https://github.com/goauthentik/authentik/issues/11874
model_name="accesstoken", # operations = [
index=models.Index(fields=["token"], name="authentik_p_token_4bc870_idx"), # migrations.AddIndex(
), # model_name="accesstoken",
migrations.AddIndex( # index=models.Index(fields=["token"], name="authentik_p_token_4bc870_idx"),
model_name="refreshtoken", # ),
index=models.Index(fields=["token"], name="authentik_p_token_1a841f_idx"), # migrations.AddIndex(
), # model_name="refreshtoken",
] # index=models.Index(fields=["token"], name="authentik_p_token_1a841f_idx"),
# ),
# ]
operations = []

View File

@ -11,21 +11,24 @@ class Migration(migrations.Migration):
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ # Original preserved
migrations.RemoveIndex( # See https://github.com/goauthentik/authentik/issues/11874
model_name="accesstoken", # operations = [
name="authentik_p_token_4bc870_idx", # migrations.RemoveIndex(
), # model_name="accesstoken",
migrations.RemoveIndex( # name="authentik_p_token_4bc870_idx",
model_name="refreshtoken", # ),
name="authentik_p_token_1a841f_idx", # migrations.RemoveIndex(
), # model_name="refreshtoken",
migrations.AddIndex( # name="authentik_p_token_1a841f_idx",
model_name="accesstoken", # ),
index=models.Index(fields=["token", "provider"], name="authentik_p_token_f99422_idx"), # migrations.AddIndex(
), # model_name="accesstoken",
migrations.AddIndex( # index=models.Index(fields=["token", "provider"], name="authentik_p_token_f99422_idx"),
model_name="refreshtoken", # ),
index=models.Index(fields=["token", "provider"], name="authentik_p_token_a1d921_idx"), # migrations.AddIndex(
), # model_name="refreshtoken",
] # index=models.Index(fields=["token", "provider"], name="authentik_p_token_a1d921_idx"),
# ),
# ]
operations = []

View File

@ -0,0 +1,31 @@
# Generated by Django 5.0.9 on 2024-10-31 14:28
import django.contrib.postgres.indexes
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0040_provider_invalidation_flow"),
("authentik_providers_oauth2", "0022_remove_accesstoken_session_id_and_more"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RunSQL("DROP INDEX IF EXISTS authentik_p_token_f99422_idx;"),
migrations.RunSQL("DROP INDEX IF EXISTS authentik_p_token_a1d921_idx;"),
migrations.AddIndex(
model_name="accesstoken",
index=django.contrib.postgres.indexes.HashIndex(
fields=["token"], name="authentik_p_token_e00883_hash"
),
),
migrations.AddIndex(
model_name="refreshtoken",
index=django.contrib.postgres.indexes.HashIndex(
fields=["token"], name="authentik_p_token_32e2b7_hash"
),
),
]

View File

@ -13,6 +13,7 @@ from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
from dacite.core import from_dict from dacite.core import from_dict
from django.contrib.postgres.indexes import HashIndex
from django.db import models from django.db import models
from django.http import HttpRequest from django.http import HttpRequest
from django.templatetags.static import static from django.templatetags.static import static
@ -418,7 +419,7 @@ class AccessToken(SerializerModel, ExpiringModel, BaseGrantModel):
class Meta: class Meta:
indexes = [ indexes = [
models.Index(fields=["token", "provider"]), HashIndex(fields=["token"]),
] ]
verbose_name = _("OAuth2 Access Token") verbose_name = _("OAuth2 Access Token")
verbose_name_plural = _("OAuth2 Access Tokens") verbose_name_plural = _("OAuth2 Access Tokens")
@ -464,7 +465,7 @@ class RefreshToken(SerializerModel, ExpiringModel, BaseGrantModel):
class Meta: class Meta:
indexes = [ indexes = [
models.Index(fields=["token", "provider"]), HashIndex(fields=["token"]),
] ]
verbose_name = _("OAuth2 Refresh Token") verbose_name = _("OAuth2 Refresh Token")
verbose_name_plural = _("OAuth2 Refresh Tokens") verbose_name_plural = _("OAuth2 Refresh Tokens")

View File

@ -3,6 +3,7 @@
from urllib.parse import urlencode from urllib.parse import urlencode
from django.urls import reverse from django.urls import reverse
from rest_framework.test import APIClient
from authentik.core.models import Application, Group from authentik.core.models import Application, Group
from authentik.core.tests.utils import create_test_admin_user, create_test_brand, create_test_flow from authentik.core.tests.utils import create_test_admin_user, create_test_brand, create_test_flow
@ -34,7 +35,10 @@ class TesOAuth2DeviceInit(OAuthTestCase):
self.brand.flow_device_code = self.device_flow self.brand.flow_device_code = self.device_flow
self.brand.save() self.brand.save()
def test_device_init(self): self.api_client = APIClient()
self.api_client.force_login(self.user)
def test_device_init_get(self):
"""Test device init""" """Test device init"""
res = self.client.get(reverse("authentik_providers_oauth2_root:device-login")) res = self.client.get(reverse("authentik_providers_oauth2_root:device-login"))
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
@ -48,6 +52,76 @@ class TesOAuth2DeviceInit(OAuthTestCase):
), ),
) )
def test_device_init_post(self):
"""Test device init"""
res = self.api_client.get(reverse("authentik_providers_oauth2_root:device-login"))
self.assertEqual(res.status_code, 302)
self.assertEqual(
res.url,
reverse(
"authentik_core:if-flow",
kwargs={
"flow_slug": self.device_flow.slug,
},
),
)
res = self.api_client.get(
reverse(
"authentik_api:flow-executor",
kwargs={
"flow_slug": self.device_flow.slug,
},
),
)
self.assertEqual(res.status_code, 200)
self.assertJSONEqual(
res.content,
{
"component": "ak-provider-oauth2-device-code",
"flow_info": {
"background": "/static/dist/assets/images/flow_background.jpg",
"cancel_url": "/flows/-/cancel/",
"layout": "stacked",
"title": self.device_flow.title,
},
},
)
provider = OAuth2Provider.objects.create(
name=generate_id(),
authorization_flow=create_test_flow(),
)
Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
token = DeviceToken.objects.create(
provider=provider,
)
res = self.api_client.post(
reverse(
"authentik_api:flow-executor",
kwargs={
"flow_slug": self.device_flow.slug,
},
),
data={
"component": "ak-provider-oauth2-device-code",
"code": token.user_code,
},
)
self.assertEqual(res.status_code, 200)
self.assertJSONEqual(
res.content,
{
"component": "xak-flow-redirect",
"to": reverse(
"authentik_core:if-flow",
kwargs={
"flow_slug": provider.authorization_flow.slug,
},
),
},
)
def test_no_flow(self): def test_no_flow(self):
"""Test no flow""" """Test no flow"""
self.brand.flow_device_code = None self.brand.flow_device_code = None

View File

@ -5,7 +5,7 @@ from typing import Any
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.fields import CharField, IntegerField from rest_framework.fields import CharField
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.brands.models import Brand from authentik.brands.models import Brand
@ -47,6 +47,9 @@ class CodeValidatorView(PolicyAccessView):
self.provider = self.token.provider self.provider = self.token.provider
self.application = self.token.provider.application self.application = self.token.provider.application
def post(self, request: HttpRequest, *args, **kwargs):
return self.get(request, *args, **kwargs)
def get(self, request: HttpRequest, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs):
scope_descriptions = UserInfoView().get_scope_descriptions(self.token.scope, self.provider) scope_descriptions = UserInfoView().get_scope_descriptions(self.token.scope, self.provider)
planner = FlowPlanner(self.provider.authorization_flow) planner = FlowPlanner(self.provider.authorization_flow)
@ -122,7 +125,7 @@ class OAuthDeviceCodeChallenge(Challenge):
class OAuthDeviceCodeChallengeResponse(ChallengeResponse): class OAuthDeviceCodeChallengeResponse(ChallengeResponse):
"""Response that includes the user-entered device code""" """Response that includes the user-entered device code"""
code = IntegerField() code = CharField()
component = CharField(default="ak-provider-oauth2-device-code") component = CharField(default="ak-provider-oauth2-device-code")
def validate_code(self, code: int) -> HttpResponse | None: def validate_code(self, code: int) -> HttpResponse | None:

View File

@ -17,6 +17,7 @@ class CaptchaStageSerializer(StageSerializer):
"private_key", "private_key",
"js_url", "js_url",
"api_url", "api_url",
"interactive",
"score_min_threshold", "score_min_threshold",
"score_max_threshold", "score_max_threshold",
"error_on_invalid_score", "error_on_invalid_score",

View File

@ -0,0 +1,18 @@
# Generated by Django 5.0.9 on 2024-10-30 14:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_captcha", "0003_captchastage_error_on_invalid_score_and_more"),
]
operations = [
migrations.AddField(
model_name="captchastage",
name="interactive",
field=models.BooleanField(default=False),
),
]

View File

@ -9,11 +9,13 @@ from authentik.flows.models import Stage
class CaptchaStage(Stage): class CaptchaStage(Stage):
"""Verify the user is human using Google's reCaptcha.""" """Verify the user is human using Google's reCaptcha/other compatible CAPTCHA solutions."""
public_key = models.TextField(help_text=_("Public key, acquired your captcha Provider.")) public_key = models.TextField(help_text=_("Public key, acquired your captcha Provider."))
private_key = models.TextField(help_text=_("Private key, acquired your captcha Provider.")) private_key = models.TextField(help_text=_("Private key, acquired your captcha Provider."))
interactive = models.BooleanField(default=False)
score_min_threshold = models.FloatField(default=0.5) # Default values for reCaptcha score_min_threshold = models.FloatField(default=0.5) # Default values for reCaptcha
score_max_threshold = models.FloatField(default=1.0) # Default values for reCaptcha score_max_threshold = models.FloatField(default=1.0) # Default values for reCaptcha

View File

@ -3,7 +3,7 @@
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from requests import RequestException from requests import RequestException
from rest_framework.fields import CharField from rest_framework.fields import BooleanField, CharField
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -24,10 +24,12 @@ PLAN_CONTEXT_CAPTCHA = "captcha"
class CaptchaChallenge(WithUserInfoChallenge): class CaptchaChallenge(WithUserInfoChallenge):
"""Site public key""" """Site public key"""
site_key = CharField()
js_url = CharField()
component = CharField(default="ak-stage-captcha") component = CharField(default="ak-stage-captcha")
site_key = CharField(required=True)
js_url = CharField(required=True)
interactive = BooleanField(required=True)
def verify_captcha_token(stage: CaptchaStage, token: str, remote_ip: str): def verify_captcha_token(stage: CaptchaStage, token: str, remote_ip: str):
"""Validate captcha token""" """Validate captcha token"""
@ -103,6 +105,7 @@ class CaptchaStageView(ChallengeStageView):
data={ data={
"js_url": self.executor.current_stage.js_url, "js_url": self.executor.current_stage.js_url,
"site_key": self.executor.current_stage.public_key, "site_key": self.executor.current_stage.public_key,
"interactive": self.executor.current_stage.interactive,
} }
) )

View File

@ -223,6 +223,7 @@ class IdentificationStageView(ChallengeStageView):
{ {
"js_url": current_stage.captcha_stage.js_url, "js_url": current_stage.captcha_stage.js_url,
"site_key": current_stage.captcha_stage.public_key, "site_key": current_stage.captcha_stage.public_key,
"interactive": current_stage.captcha_stage.interactive,
} }
if current_stage.captcha_stage if current_stage.captcha_stage
else None else None

View File

@ -21,7 +21,7 @@ from authentik.flows.challenge import (
WithUserInfoChallenge, WithUserInfoChallenge,
) )
from authentik.flows.exceptions import StageInvalidException from authentik.flows.exceptions import StageInvalidException
from authentik.flows.models import Flow, FlowDesignation, Stage from authentik.flows.models import Flow, Stage
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView from authentik.flows.stage import ChallengeStageView
from authentik.lib.utils.reflection import path_to_class from authentik.lib.utils.reflection import path_to_class
@ -141,11 +141,11 @@ class PasswordStageView(ChallengeStageView):
"allow_show_password": self.executor.current_stage.allow_show_password, "allow_show_password": self.executor.current_stage.allow_show_password,
} }
) )
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY) recovery_flow: Flow | None = self.request.brand.flow_recovery
if recovery_flow.exists(): if recovery_flow:
recover_url = reverse( recover_url = reverse(
"authentik_core:if-flow", "authentik_core:if-flow",
kwargs={"flow_slug": recovery_flow.first().slug}, kwargs={"flow_slug": recovery_flow.slug},
) )
challenge.initial_data["recovery_url"] = self.request.build_absolute_uri(recover_url) challenge.initial_data["recovery_url"] = self.request.build_absolute_uri(recover_url)
return challenge return challenge

View File

@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.urls import reverse from django.urls import reverse
from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.core.tests.utils import create_test_admin_user, create_test_brand, create_test_flow
from authentik.flows.markers import StageMarker from authentik.flows.markers import StageMarker
from authentik.flows.models import FlowDesignation, FlowStageBinding from authentik.flows.models import FlowDesignation, FlowStageBinding
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
@ -57,6 +57,9 @@ class TestPasswordStage(FlowTestCase):
def test_recovery_flow_link(self): def test_recovery_flow_link(self):
"""Test link to the default recovery flow""" """Test link to the default recovery flow"""
flow = create_test_flow(designation=FlowDesignation.RECOVERY) flow = create_test_flow(designation=FlowDesignation.RECOVERY)
brand = create_test_brand()
brand.flow_recovery = flow
brand.save()
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session session = self.client.session

View File

@ -101,7 +101,6 @@ entries:
- !KeyOf prompt-field-email - !KeyOf prompt-field-email
- !KeyOf prompt-field-password - !KeyOf prompt-field-password
- !KeyOf prompt-field-password-repeat - !KeyOf prompt-field-password-repeat
validation_policies: []
id: stage-default-oobe-password id: stage-default-oobe-password
identifiers: identifiers:
name: stage-default-oobe-password name: stage-default-oobe-password

View File

@ -2,6 +2,17 @@ version: 1
metadata: metadata:
name: Default - Password change flow name: Default - Password change flow
entries: entries:
- attrs:
check_static_rules: true
check_zxcvbn: true
length_min: 8
password_field: password
zxcvbn_score_threshold: 2
error_message: Password needs to be 8 characters or longer.
identifiers:
name: default-password-change-password-policy
model: authentik_policies_password.passwordpolicy
id: default-password-change-password-policy
- attrs: - attrs:
designation: stage_configuration designation: stage_configuration
name: Change Password name: Change Password
@ -39,6 +50,8 @@ entries:
fields: fields:
- !KeyOf prompt-field-password - !KeyOf prompt-field-password
- !KeyOf prompt-field-password-repeat - !KeyOf prompt-field-password-repeat
validation_policies:
- !KeyOf default-password-change-password-policy
identifiers: identifiers:
name: default-password-change-prompt name: default-password-change-prompt
id: default-password-change-prompt id: default-password-change-prompt

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema", "$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json", "$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object", "type": "object",
"title": "authentik 2024.10.0 Blueprint schema", "title": "authentik 2024.10.2 Blueprint schema",
"required": [ "required": [
"version", "version",
"entries" "entries"
@ -6974,7 +6974,7 @@
"spnego_server_name": { "spnego_server_name": {
"type": "string", "type": "string",
"title": "Spnego server name", "title": "Spnego server name",
"description": "Force the use of a specific server name for SPNEGO" "description": "Force the use of a specific server name for SPNEGO. Must be in the form HTTP@hostname"
}, },
"spnego_keytab": { "spnego_keytab": {
"type": "string", "type": "string",
@ -9781,6 +9781,10 @@
"minLength": 1, "minLength": 1,
"title": "Api url" "title": "Api url"
}, },
"interactive": {
"type": "boolean",
"title": "Interactive"
},
"score_min_threshold": { "score_min_threshold": {
"type": "number", "type": "number",
"title": "Score min threshold" "title": "Score min threshold"
@ -13383,12 +13387,6 @@
"title": "Authorization flow", "title": "Authorization flow",
"description": "Flow used when authorizing this provider." "description": "Flow used when authorizing this provider."
}, },
"invalidation_flow": {
"type": "string",
"format": "uuid",
"title": "Invalidation flow",
"description": "Flow used ending the session from a provider."
},
"property_mappings": { "property_mappings": {
"type": "array", "type": "array",
"items": { "items": {

View File

@ -31,7 +31,7 @@ services:
volumes: volumes:
- redis:/data - redis:/data
server: server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.2}
restart: unless-stopped restart: unless-stopped
command: server command: server
environment: environment:
@ -52,7 +52,7 @@ services:
- postgresql - postgresql
- redis - redis
worker: worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.0} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.2}
restart: unless-stopped restart: unless-stopped
command: worker command: worker
environment: environment:

2
go.mod
View File

@ -29,7 +29,7 @@ require (
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/wwt/guac v1.3.2 github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2024100.1 goauthentik.io/api/v3 v3.2024083.13
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.23.0 golang.org/x/oauth2 v0.23.0
golang.org/x/sync v0.8.0 golang.org/x/sync v0.8.0

4
go.sum
View File

@ -299,8 +299,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
goauthentik.io/api/v3 v3.2024100.1 h1:ve8xiaKOyUD5oCkNAsu1o3nc7aolt9bKTTR2qMI1iU4= goauthentik.io/api/v3 v3.2024083.13 h1:xKh3feJYUeLw583zZ5ifgV0qjD37ZCOzgXPfbHQSbHM=
goauthentik.io/api/v3 v3.2024100.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= goauthentik.io/api/v3 v3.2024083.13/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=

View File

@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion()) return fmt.Sprintf("authentik@%s", FullVersion())
} }
const VERSION = "2024.10.0" const VERSION = "2024.10.2"

View File

@ -23,6 +23,7 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"goauthentik.io/api/v3" "goauthentik.io/api/v3"
"goauthentik.io/internal/config"
"goauthentik.io/internal/outpost/ak" "goauthentik.io/internal/outpost/ak"
"goauthentik.io/internal/outpost/proxyv2/constants" "goauthentik.io/internal/outpost/proxyv2/constants"
"goauthentik.io/internal/outpost/proxyv2/hs256" "goauthentik.io/internal/outpost/proxyv2/hs256"
@ -121,6 +122,14 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server, old
bs := string(h.Sum([]byte(*p.ClientId))) bs := string(h.Sum([]byte(*p.ClientId)))
sessionName := fmt.Sprintf("authentik_proxy_%s", bs[:8]) sessionName := fmt.Sprintf("authentik_proxy_%s", bs[:8])
// When HOST_BROWSER is set, use that as Host header for token requests to make the issuer match
// otherwise we use the internally configured authentik_host
tokenEndpointHost := server.API().Outpost.Config["authentik_host"].(string)
if config.Get().AuthentikHostBrowser != "" {
tokenEndpointHost = config.Get().AuthentikHostBrowser
}
publicHTTPClient := web.NewHostInterceptor(c, tokenEndpointHost)
a := &Application{ a := &Application{
Host: externalHost.Host, Host: externalHost.Host,
log: muxLogger, log: muxLogger,
@ -131,7 +140,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server, old
tokenVerifier: verifier, tokenVerifier: verifier,
proxyConfig: p, proxyConfig: p,
httpClient: c, httpClient: c,
publicHostHTTPClient: web.NewHostInterceptor(c, server.API().Outpost.Config["authentik_host"].(string)), publicHostHTTPClient: publicHTTPClient,
mux: mux, mux: mux,
errorTemplates: templates.GetTemplates(), errorTemplates: templates.GetTemplates(),
ak: server.API(), ak: server.API(),

View File

@ -14,8 +14,10 @@ type hostInterceptor struct {
} }
func (t hostInterceptor) RoundTrip(r *http.Request) (*http.Response, error) { func (t hostInterceptor) RoundTrip(r *http.Request) (*http.Response, error) {
r.Host = t.host if r.Host != t.host {
r.Header.Set("X-Forwarded-Proto", t.scheme) r.Host = t.host
r.Header.Set("X-Forwarded-Proto", t.scheme)
}
return t.inner.RoundTrip(r) return t.inner.RoundTrip(r)
} }

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-28 00:09+0000\n" "POT-Creation-Date: 2024-10-23 16:39+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -2614,7 +2614,12 @@ msgid "Captcha Stages"
msgstr "" msgstr ""
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response. Retrying may solve this issue." msgid "Unknown error"
msgstr ""
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "" msgstr ""
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py

View File

@ -11,17 +11,15 @@
# Marco Vitale, 2024 # Marco Vitale, 2024
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2024 # Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2024
# albanobattistella <albanobattistella@gmail.com>, 2024 # albanobattistella <albanobattistella@gmail.com>, 2024
# Nicola Mersi, 2024
# tom max, 2024
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-28 00:09+0000\n" "POT-Creation-Date: 2024-10-18 00:09+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: tom max, 2024\n" "Last-Translator: albanobattistella <albanobattistella@gmail.com>, 2024\n"
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n" "Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -585,28 +583,6 @@ msgstr "Limite massimo di connessioni raggiunto."
msgid "(You are already connected in another tab/window)" msgid "(You are already connected in another tab/window)"
msgstr "(Sei già connesso in un'altra scheda/finestra)" msgstr "(Sei già connesso in un'altra scheda/finestra)"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
msgstr ""
"Fase di autenticazione per la verifica dispositivo Google tramite endpoint"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stages"
msgstr ""
"Fasi di autenticazione per la verifica dispositivo Google tramite endpoint"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Device"
msgstr "Dispositivo di Accesso"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Devices"
msgstr "Dispositivi di Accesso"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/stage.py
msgid "Verifying your browser..."
msgstr "Verifica del tuo browser..."
#: authentik/enterprise/stages/source/models.py #: authentik/enterprise/stages/source/models.py
msgid "" msgid ""
"Amount of time a user can take to return from the source to continue the " "Amount of time a user can take to return from the source to continue the "
@ -2041,124 +2017,6 @@ msgstr ""
msgid "Used recovery-link to authenticate." msgid "Used recovery-link to authenticate."
msgstr "Utilizzato il link di recupero per autenticarsi." msgstr "Utilizzato il link di recupero per autenticarsi."
#: authentik/sources/kerberos/models.py
msgid "Kerberos realm"
msgstr "Dominio Kerberos"
#: authentik/sources/kerberos/models.py
msgid "Custom krb5.conf to use. Uses the system one by default"
msgstr ""
"krb5.conf personalizzato da usare. Usa la configurazione di sistema per "
"default"
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
msgstr "Sincronizza utenti da Kerberos a authentik"
#: authentik/sources/kerberos/models.py
msgid "When a user changes their password, sync it back to Kerberos"
msgstr "Quando un utente cambia la sua password, sincronizzala in Kerberos"
#: authentik/sources/kerberos/models.py
msgid "Principal to authenticate to kadmin for sync."
msgstr "Entità da autenticare su kadmin per la sincronizzazione."
#: authentik/sources/kerberos/models.py
msgid "Password to authenticate to kadmin for sync"
msgstr "Password per autenticarsi in kadmin per sincronizzare"
#: authentik/sources/kerberos/models.py
msgid ""
"Keytab to authenticate to kadmin for sync. Must be base64-encoded or in the "
"form TYPE:residual"
msgstr ""
"Keytab per autenticarsi su kadmin per la sincronizzazione. Deve essere con "
"codifica base64 o nel formato TYPE:residual"
#: authentik/sources/kerberos/models.py
msgid ""
"Credentials cache to authenticate to kadmin for sync. Must be in the form "
"TYPE:residual"
msgstr ""
"Credenziali memorizzate nella cache per autenticarsi su kadmin per la "
"sincronizzazione. Devono essere nel formato TYPE:residual"
#: authentik/sources/kerberos/models.py
msgid ""
"Force the use of a specific server name for SPNEGO. Must be in the form "
"HTTP@hostname"
msgstr ""
"Forza l'uso di un nome server specifico per SPNEGO. Deve essere nel formato "
"HTTP@nomehost"
#: authentik/sources/kerberos/models.py
msgid "SPNEGO keytab base64-encoded or path to keytab in the form FILE:path"
msgstr ""
"keytab SPNEGO con codifica base64 o percorso del keytab nel formato "
"FILE:percorso"
#: authentik/sources/kerberos/models.py
msgid "Credential cache to use for SPNEGO in form type:residual"
msgstr ""
"Cache delle credenziali da utilizzare per SPNEGO nella forma type:residual"
#: authentik/sources/kerberos/models.py
msgid ""
"If enabled, the authentik-stored password will be updated upon login with "
"the Kerberos password backend"
msgstr ""
"Se abilitato, la password memorizzata in authentik verrà aggiornata al login"
" nel backend Kerberos"
#: authentik/sources/kerberos/models.py
msgid "Kerberos Source"
msgstr "Sorgente Kerberos"
#: authentik/sources/kerberos/models.py
msgid "Kerberos Sources"
msgstr "Sorgenti Kerberos"
#: authentik/sources/kerberos/models.py
msgid "Kerberos Source Property Mapping"
msgstr "Mappa delle proprietà della sorgente kerberos"
#: authentik/sources/kerberos/models.py
msgid "Kerberos Source Property Mappings"
msgstr "Mappe delle proprietà della sorgente kerberos"
#: authentik/sources/kerberos/models.py
msgid "User Kerberos Source Connection"
msgstr "Connessione sorgente dell'utente kerberos"
#: authentik/sources/kerberos/models.py
msgid "User Kerberos Source Connections"
msgstr " Connessioni alle sorgente dell'utente kerberos"
#: authentik/sources/kerberos/models.py
msgid "Group Kerberos Source Connection"
msgstr " Connessione sorgente del gruppo kerberos"
#: authentik/sources/kerberos/models.py
msgid "Group Kerberos Source Connections"
msgstr "Connessioni alle sorgenti del gruppo kerberos"
#: authentik/sources/kerberos/views.py
msgid "SPNEGO authentication required"
msgstr "autenticazione SPNEGO necessaria"
#: authentik/sources/kerberos/views.py
msgid ""
"\n"
" Make sure you have valid tickets (obtainable via kinit)\n"
" and configured the browser correctly.\n"
" Please contact your administrator.\n"
" "
msgstr ""
"\n"
"Assicurati di avere un ticket valido (ottenibile tramite kinit)\n"
" e di aver configurato correttamente il browser. \n"
"Contatta il tuo amministratore."
#: authentik/sources/ldap/api.py #: authentik/sources/ldap/api.py
msgid "Only a single LDAP Source with password synchronization is allowed" msgid "Only a single LDAP Source with password synchronization is allowed"
msgstr "" msgstr ""
@ -2877,10 +2735,13 @@ msgid "Captcha Stages"
msgstr "Fasi Captcha" msgstr "Fasi Captcha"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response. Retrying may solve this issue." msgid "Unknown error"
msgstr "" msgstr "Errore sconosciuto"
"Risposta captcha non valida. Un nuovo tentativo potrebbe risolvere il "
"problema." #: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "Impossibile convalidare il token: {error}"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response" msgid "Invalid captcha response"
@ -3253,10 +3114,6 @@ msgstr "Database utente + password app"
msgid "User database + LDAP password" msgid "User database + LDAP password"
msgstr "Database utenti + password LDAP" msgstr "Database utenti + password LDAP"
#: authentik/stages/password/models.py
msgid "User database + Kerberos password"
msgstr "Database utenti + password Kerberos"
#: authentik/stages/password/models.py #: authentik/stages/password/models.py
msgid "Selection of backends to test the password against." msgid "Selection of backends to test the password against."
msgstr "Selezione di backend su cui testare la password." msgstr "Selezione di backend su cui testare la password."

Binary file not shown.

View File

@ -15,7 +15,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-28 00:09+0000\n" "POT-Creation-Date: 2024-10-23 16:39+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2024\n" "Last-Translator: deluxghost, 2024\n"
"Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n" "Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n"
@ -2649,8 +2649,13 @@ msgid "Captcha Stages"
msgstr "验证码阶段" msgstr "验证码阶段"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response. Retrying may solve this issue." msgid "Unknown error"
msgstr "无效的验证码响应。重试可能会解决此问题。" msgstr "未知错误"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "验证令牌失败:{error}"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response" msgid "Invalid captcha response"

View File

@ -14,7 +14,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-28 00:09+0000\n" "POT-Creation-Date: 2024-10-23 16:39+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2024\n" "Last-Translator: deluxghost, 2024\n"
"Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n" "Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n"
@ -2648,8 +2648,13 @@ msgid "Captcha Stages"
msgstr "验证码阶段" msgstr "验证码阶段"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response. Retrying may solve this issue." msgid "Unknown error"
msgstr "无效的验证码响应。重试可能会解决此问题。" msgstr "未知错误"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "验证令牌失败:{error}"
#: authentik/stages/captcha/stage.py #: authentik/stages/captcha/stage.py
msgid "Invalid captcha response" msgid "Invalid captcha response"

View File

@ -1,5 +1,5 @@
{ {
"name": "@goauthentik/authentik", "name": "@goauthentik/authentik",
"version": "2024.10.0", "version": "2024.10.2",
"private": true "private": true
} }

28
poetry.lock generated
View File

@ -3896,13 +3896,13 @@ pytest = ">=4.0.0"
[[package]] [[package]]
name = "pytest-randomly" name = "pytest-randomly"
version = "3.16.0" version = "3.15.0"
description = "Pytest plugin to randomly order tests and control random.seed." description = "Pytest plugin to randomly order tests and control random.seed."
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.8"
files = [ files = [
{file = "pytest_randomly-3.16.0-py3-none-any.whl", hash = "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6"}, {file = "pytest_randomly-3.15.0-py3-none-any.whl", hash = "sha256:0516f4344b29f4e9cdae8bce31c4aeebf59d0b9ef05927c33354ff3859eeeca6"},
{file = "pytest_randomly-3.16.0.tar.gz", hash = "sha256:11bf4d23a26484de7860d82f726c0629837cf4064b79157bd18ec9d41d7feb26"}, {file = "pytest_randomly-3.15.0.tar.gz", hash = "sha256:b908529648667ba5e54723088edd6f82252f540cc340d748d1fa985539687047"},
] ]
[package.dependencies] [package.dependencies]
@ -4354,13 +4354,13 @@ django-query = ["django (>=3.2)"]
[[package]] [[package]]
name = "selenium" name = "selenium"
version = "4.26.0" version = "4.25.0"
description = "Official Python bindings for Selenium WebDriver" description = "Official Python bindings for Selenium WebDriver"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "selenium-4.26.0-py3-none-any.whl", hash = "sha256:48013f36e812de5b3948ef53d04e73f77bc923ee3e1d7d99eaf0618179081b99"}, {file = "selenium-4.25.0-py3-none-any.whl", hash = "sha256:3798d2d12b4a570bc5790163ba57fef10b2afee958bf1d80f2a3cf07c4141f33"},
{file = "selenium-4.26.0.tar.gz", hash = "sha256:f0780f85f10310aa5d085b81e79d73d3c93b83d8de121d0400d543a50ee963e8"}, {file = "selenium-4.25.0.tar.gz", hash = "sha256:95d08d3b82fb353f3c474895154516604c7f0e6a9a565ae6498ef36c9bac6921"},
] ]
[package.dependencies] [package.dependencies]
@ -4425,13 +4425,13 @@ tornado = ["tornado (>=6)"]
[[package]] [[package]]
name = "service-identity" name = "service-identity"
version = "24.2.0" version = "24.1.0"
description = "Service identity verification for pyOpenSSL & cryptography." description = "Service identity verification for pyOpenSSL & cryptography."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "service_identity-24.2.0-py3-none-any.whl", hash = "sha256:6b047fbd8a84fd0bb0d55ebce4031e400562b9196e1e0d3e0fe2b8a59f6d4a85"}, {file = "service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"},
{file = "service_identity-24.2.0.tar.gz", hash = "sha256:b8683ba13f0d39c6cd5d625d2c5f65421d6d707b013b375c355751557cbe8e09"}, {file = "service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"},
] ]
[package.dependencies] [package.dependencies]
@ -4441,7 +4441,7 @@ pyasn1 = "*"
pyasn1-modules = "*" pyasn1-modules = "*"
[package.extras] [package.extras]
dev = ["coverage[toml] (>=5.0.2)", "idna", "mypy", "pyopenssl", "pytest", "types-pyopenssl"] dev = ["pyopenssl", "service-identity[idna,mypy,tests]"]
docs = ["furo", "myst-parser", "pyopenssl", "sphinx", "sphinx-notfound-page"] docs = ["furo", "myst-parser", "pyopenssl", "sphinx", "sphinx-notfound-page"]
idna = ["idna"] idna = ["idna"]
mypy = ["idna", "mypy", "types-pyopenssl"] mypy = ["idna", "mypy", "types-pyopenssl"]
@ -4751,13 +4751,13 @@ wsproto = ">=0.14"
[[package]] [[package]]
name = "twilio" name = "twilio"
version = "9.3.6" version = "9.3.5"
description = "Twilio API client and TwiML generator" description = "Twilio API client and TwiML generator"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.7.0"
files = [ files = [
{file = "twilio-9.3.6-py2.py3-none-any.whl", hash = "sha256:c5d7f4cfeb50a7928397b8f819c8f7fb2bb956a1a2cabbda1df1d7a40f9ce1d7"}, {file = "twilio-9.3.5-py2.py3-none-any.whl", hash = "sha256:d6a97a77b98cc176a61c960f11894af385bc1c11b93e2e8b79fdfb9601788fb0"},
{file = "twilio-9.3.6.tar.gz", hash = "sha256:d42691f7fe1faaa5ba82942f169bfea4d7f01a0a542a456d82018fb49bd1f5b2"}, {file = "twilio-9.3.5.tar.gz", hash = "sha256:608d78a903d403465aac1840c58a6546a090b7e222d2bf539a93c3831072880c"},
] ]
[package.dependencies] [package.dependencies]

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "authentik" name = "authentik"
version = "2024.10.0" version = "2024.10.2"
description = "" description = ""
authors = ["authentik Team <hello@goauthentik.io>"] authors = ["authentik Team <hello@goauthentik.io>"]

View File

@ -1,7 +1,7 @@
openapi: 3.0.3 openapi: 3.0.3
info: info:
title: authentik title: authentik
version: 2024.10.0 version: 2024.10.2
description: Making authentication simple. description: Making authentication simple.
contact: contact:
email: hello@goauthentik.io email: hello@goauthentik.io
@ -39220,7 +39220,10 @@ components:
type: string type: string
js_url: js_url:
type: string type: string
interactive:
type: boolean
required: required:
- interactive
- js_url - js_url
- pending_user - pending_user
- pending_user_avatar - pending_user_avatar
@ -39276,6 +39279,8 @@ components:
type: string type: string
api_url: api_url:
type: string type: string
interactive:
type: boolean
score_min_threshold: score_min_threshold:
type: number type: number
format: double format: double
@ -39322,6 +39327,8 @@ components:
api_url: api_url:
type: string type: string
minLength: 1 minLength: 1
interactive:
type: boolean
score_min_threshold: score_min_threshold:
type: number type: number
format: double format: double
@ -42975,7 +42982,8 @@ components:
readOnly: true readOnly: true
spnego_server_name: spnego_server_name:
type: string type: string
description: Force the use of a specific server name for SPNEGO description: Force the use of a specific server name for SPNEGO. Must be
in the form HTTP@hostname
spnego_ccache: spnego_ccache:
type: string type: string
description: Credential cache to use for SPNEGO in form type:residual description: Credential cache to use for SPNEGO in form type:residual
@ -43144,7 +43152,8 @@ components:
be in the form TYPE:residual be in the form TYPE:residual
spnego_server_name: spnego_server_name:
type: string type: string
description: Force the use of a specific server name for SPNEGO description: Force the use of a specific server name for SPNEGO. Must be
in the form HTTP@hostname
spnego_keytab: spnego_keytab:
type: string type: string
writeOnly: true writeOnly: true
@ -44934,7 +44943,8 @@ components:
minLength: 1 minLength: 1
default: ak-provider-oauth2-device-code default: ak-provider-oauth2-device-code
code: code:
type: integer type: string
minLength: 1
required: required:
- code - code
OAuthDeviceCodeFinishChallenge: OAuthDeviceCodeFinishChallenge:
@ -47730,6 +47740,8 @@ components:
api_url: api_url:
type: string type: string
minLength: 1 minLength: 1
interactive:
type: boolean
score_min_threshold: score_min_threshold:
type: number type: number
format: double format: double
@ -48448,7 +48460,8 @@ components:
be in the form TYPE:residual be in the form TYPE:residual
spnego_server_name: spnego_server_name:
type: string type: string
description: Force the use of a specific server name for SPNEGO description: Force the use of a specific server name for SPNEGO. Must be
in the form HTTP@hostname
spnego_keytab: spnego_keytab:
type: string type: string
writeOnly: true writeOnly: true
@ -49461,10 +49474,6 @@ components:
type: string type: string
format: uuid format: uuid
description: Flow used when authorizing this provider. description: Flow used when authorizing this provider.
invalidation_flow:
type: string
format: uuid
description: Flow used ending the session from a provider.
property_mappings: property_mappings:
type: array type: array
items: items:
@ -51696,10 +51705,6 @@ components:
type: string type: string
format: uuid format: uuid
description: Flow used when authorizing this provider. description: Flow used when authorizing this provider.
invalidation_flow:
type: string
format: uuid
description: Flow used ending the session from a provider.
property_mappings: property_mappings:
type: array type: array
items: items:
@ -51757,7 +51762,6 @@ components:
- assigned_backchannel_application_slug - assigned_backchannel_application_slug
- authorization_flow - authorization_flow
- component - component
- invalidation_flow
- meta_model_name - meta_model_name
- name - name
- outpost_set - outpost_set
@ -51781,10 +51785,6 @@ components:
type: string type: string
format: uuid format: uuid
description: Flow used when authorizing this provider. description: Flow used when authorizing this provider.
invalidation_flow:
type: string
format: uuid
description: Flow used ending the session from a provider.
property_mappings: property_mappings:
type: array type: array
items: items:
@ -51801,7 +51801,6 @@ components:
description: When set to true, connection tokens will be deleted upon disconnect. description: When set to true, connection tokens will be deleted upon disconnect.
required: required:
- authorization_flow - authorization_flow
- invalidation_flow
- name - name
RadiusCheckAccess: RadiusCheckAccess:
type: object type: object

View File

@ -66,7 +66,6 @@ const rawCssImportMaps = [
'import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";', 'import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";',
'import PFTable from "@patternfly/patternfly/components/Table/table.css";', 'import PFTable from "@patternfly/patternfly/components/Table/table.css";',
'import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";', 'import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";',
'import PFText from "@patternfly/patternfly/utilities/Text/text.css";',
'import PFTitle from "@patternfly/patternfly/components/Title/title.css";', 'import PFTitle from "@patternfly/patternfly/components/Title/title.css";',
'import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";', 'import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";',
'import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";', 'import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";',

View File

@ -119,13 +119,22 @@ async function buildOneSource(source, dest) {
Date.now() - start Date.now() - start
}ms`, }ms`,
); );
return 0;
} catch (exc) { } catch (exc) {
console.error(`[${new Date(Date.now()).toISOString()}] Failed to build ${source}: ${exc}`); console.error(`[${new Date(Date.now()).toISOString()}] Failed to build ${source}: ${exc}`);
return 1;
} }
} }
async function buildAuthentik(interfaces) { async function buildAuthentik(interfaces) {
await Promise.allSettled(interfaces.map(([source, dest]) => buildOneSource(source, dest))); const code = await Promise.allSettled(
interfaces.map(([source, dest]) => buildOneSource(source, dest)),
);
const finalCode = code.reduce((a, res) => a + res.value, 0);
if (finalCode > 0) {
return 1;
}
return 0;
} }
let timeoutId = null; let timeoutId = null;
@ -163,11 +172,12 @@ if (process.argv.length > 2 && (process.argv[2] === "-w" || process.argv[2] ===
}); });
} else if (process.argv.length > 2 && (process.argv[2] === "-p" || process.argv[2] === "--proxy")) { } else if (process.argv.length > 2 && (process.argv[2] === "-p" || process.argv[2] === "--proxy")) {
// There's no watch-for-proxy, sorry. // There's no watch-for-proxy, sorry.
await buildAuthentik( process.exit(
interfaces.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)), await buildAuthentik(
interfaces.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
),
); );
process.exit(0);
} else { } else {
// And the fallback: just build it. // And the fallback: just build it.
await buildAuthentik(interfaces); process.exit(await buildAuthentik(interfaces));
} }

341
web/package-lock.json generated
View File

@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.11", "@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7", "@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0", "@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2024.10.0-1730331602", "@goauthentik/api": "^2024.10.1-1731327664",
"@lit-labs/ssr": "^3.2.2", "@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2", "@lit/localize": "^0.12.2",
@ -1014,9 +1014,9 @@
} }
}, },
"node_modules/@codemirror/commands": { "node_modules/@codemirror/commands": {
"version": "6.7.0", "version": "6.6.2",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.7.0.tgz", "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.2.tgz",
"integrity": "sha512-+cduIZ2KbesDhbykV02K25A5xIVrquSPz4UxxYBemRlAT2aW8dhwUgLDwej7q/RJUHKk4nALYcR1puecDvbdqw==", "integrity": "sha512-Fq7eWOl1Rcbrfn6jD8FPCj9Auaxdm5nIK5RYOeW7ughnd/rY5AmPg6b+CfsG39ZHdwiwe8lde3q8uR7CF5S0yQ==",
"dependencies": { "dependencies": {
"@codemirror/language": "^6.0.0", "@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.4.0", "@codemirror/state": "^6.4.0",
@ -1775,9 +1775,9 @@
} }
}, },
"node_modules/@goauthentik/api": { "node_modules/@goauthentik/api": {
"version": "2024.10.0-1730331602", "version": "2024.10.1-1731327664",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.10.0-1730331602.tgz", "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.10.1-1731327664.tgz",
"integrity": "sha512-VaXywdDCFkIs9RgmHVYt8jGf5xnc+czsu5ILEThNQOuXvBjkGa0J8aPWVSdfP++GiHnkjddWVFzJ6R6LOoHbWQ==" "integrity": "sha512-svzKZAXsmsrSfGbTOhhFgE5kAb0vv2sIJAhXSYd1i7ua6OglZV6Qs531XhoK5QU8AFL55D8Un1U5QZ16ZFGANA=="
}, },
"node_modules/@goauthentik/web": { "node_modules/@goauthentik/web": {
"resolved": "", "resolved": "",
@ -1953,9 +1953,9 @@
} }
}, },
"node_modules/@inquirer/figures": { "node_modules/@inquirer/figures": {
"version": "1.0.7", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz",
"integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==", "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@ -2425,9 +2425,9 @@
} }
}, },
"node_modules/@lezer/javascript": { "node_modules/@lezer/javascript": {
"version": "1.4.19", "version": "1.4.18",
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.19.tgz", "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.18.tgz",
"integrity": "sha512-j44kbR1QL26l6dMunZ1uhKBFteVGLVCBGNUD2sUaMnic+rbTviVuoK0CD1l9FTW31EueWvFFswCKMH7Z+M3JRA==", "integrity": "sha512-Y8BeHOt4LtcxJgXwadtfSeWPrh0XzklcCHnCVT+vOsxqH4gWmunP2ykX+VVOlM/dusyVyiNfG3lv0f10UK+mgA==",
"dependencies": { "dependencies": {
"@lezer/common": "^1.2.0", "@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.1.3", "@lezer/highlight": "^1.1.3",
@ -2507,9 +2507,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@lit/context": { "node_modules/@lit/context": {
"version": "1.1.3", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@lit/context/-/context-1.1.3.tgz", "resolved": "https://registry.npmjs.org/@lit/context/-/context-1.1.2.tgz",
"integrity": "sha512-Auh37F4S0PZM93HTDfZWs97mmzaQ7M3vnTc9YvxAGyP3UItSK/8Fs0vTOGT+njuvOwbKio/l8Cx/zWL4vkutpQ==", "integrity": "sha512-S0nw2C6Tkm7fVX5TGYqeROGD+Z9Coa2iFpW+ysYBDH3YvCqOY3wVQvSgwbaliLJkjTnSEYCBe9qFqKV8WUFpVw==",
"dependencies": { "dependencies": {
"@lit/reactive-element": "^1.6.2 || ^2.0.0" "@lit/reactive-element": "^1.6.2 || ^2.0.0"
} }
@ -3517,6 +3517,12 @@
"win32" "win32"
] ]
}, },
"node_modules/@scarf/scarf": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
"hasInstallScript": true
},
"node_modules/@sec-ant/readable-stream": { "node_modules/@sec-ant/readable-stream": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
@ -3673,9 +3679,9 @@
} }
}, },
"node_modules/@spotlightjs/overlay": { "node_modules/@spotlightjs/overlay": {
"version": "2.6.0", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-2.6.0.tgz", "resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-2.5.2.tgz",
"integrity": "sha512-UnvWi6J8MTxhUHaBxd+k2mVyQh+0sJ5MImb/UfnEOA0WhNaFl2Foo/R7ByoOIDzDGT42+mZtfEyhJzNZ5naAaQ==" "integrity": "sha512-2YCxkTCRWn9Q4x6Aan0b43EvUJEgQBLvcws1c97LO7Cgnb0iKjiLIRW0Fa8f6PO8r9AcDvaFzhk5Z93YIkwlGQ=="
}, },
"node_modules/@spotlightjs/sidecar": { "node_modules/@spotlightjs/sidecar": {
"version": "1.8.0", "version": "1.8.0",
@ -3694,11 +3700,11 @@
} }
}, },
"node_modules/@spotlightjs/spotlight": { "node_modules/@spotlightjs/spotlight": {
"version": "2.5.0", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-2.4.2.tgz",
"integrity": "sha512-tOlefTjOUuNGyHtt1+r1IdY5vq9Hq9Vi2HqPENZ9orS/12KMEK6rVFliWT0/IXJLH5LdunNGaw3kan08bsA+NQ==", "integrity": "sha512-d7wEvG6fyP9OsqgJ3fD2YZ2zjtD9MzIuOpqTg+LAT1FXl7yBK9LRrLW/LU6OvwRdDCzUsbnxUv0giJ5DjV+2Lw==",
"dependencies": { "dependencies": {
"@spotlightjs/overlay": "2.6.0", "@spotlightjs/overlay": "2.5.2",
"@spotlightjs/sidecar": "1.8.0", "@spotlightjs/sidecar": "1.8.0",
"import-meta-resolve": "^4.1.0" "import-meta-resolve": "^4.1.0"
}, },
@ -5879,9 +5885,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/mocha": { "node_modules/@types/mocha": {
"version": "10.0.9", "version": "10.0.8",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz",
"integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==",
"dev": true "dev": true
}, },
"node_modules/@types/mute-stream": { "node_modules/@types/mute-stream": {
@ -5894,9 +5900,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.7.5", "version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -6077,16 +6083,16 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz",
"integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==", "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.8.1", "@typescript-eslint/scope-manager": "8.8.0",
"@typescript-eslint/type-utils": "8.8.1", "@typescript-eslint/type-utils": "8.8.0",
"@typescript-eslint/utils": "8.8.1", "@typescript-eslint/utils": "8.8.0",
"@typescript-eslint/visitor-keys": "8.8.1", "@typescript-eslint/visitor-keys": "8.8.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -6110,15 +6116,15 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz",
"integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.8.1", "@typescript-eslint/scope-manager": "8.8.0",
"@typescript-eslint/types": "8.8.1", "@typescript-eslint/types": "8.8.0",
"@typescript-eslint/typescript-estree": "8.8.1", "@typescript-eslint/typescript-estree": "8.8.0",
"@typescript-eslint/visitor-keys": "8.8.1", "@typescript-eslint/visitor-keys": "8.8.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -6138,13 +6144,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
"integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==", "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.8.1", "@typescript-eslint/types": "8.8.0",
"@typescript-eslint/visitor-keys": "8.8.1" "@typescript-eslint/visitor-keys": "8.8.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -6155,13 +6161,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz",
"integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==", "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.8.1", "@typescript-eslint/typescript-estree": "8.8.0",
"@typescript-eslint/utils": "8.8.1", "@typescript-eslint/utils": "8.8.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^1.3.0" "ts-api-utils": "^1.3.0"
}, },
@ -6179,9 +6185,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
"integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -6192,13 +6198,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
"integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==", "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.8.1", "@typescript-eslint/types": "8.8.0",
"@typescript-eslint/visitor-keys": "8.8.1", "@typescript-eslint/visitor-keys": "8.8.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -6220,15 +6226,15 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
"integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.8.1", "@typescript-eslint/scope-manager": "8.8.0",
"@typescript-eslint/types": "8.8.1", "@typescript-eslint/types": "8.8.0",
"@typescript-eslint/typescript-estree": "8.8.1" "@typescript-eslint/typescript-estree": "8.8.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -6242,12 +6248,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
"integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.8.1", "@typescript-eslint/types": "8.8.0",
"eslint-visitor-keys": "^3.4.3" "eslint-visitor-keys": "^3.4.3"
}, },
"engines": { "engines": {
@ -6843,9 +6849,9 @@
} }
}, },
"node_modules/@wdio/cli/node_modules/@types/node": { "node_modules/@wdio/cli/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -6971,9 +6977,9 @@
} }
}, },
"node_modules/@wdio/local-runner/node_modules/@types/node": { "node_modules/@wdio/local-runner/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -7024,9 +7030,9 @@
} }
}, },
"node_modules/@wdio/mocha-framework/node_modules/@types/node": { "node_modules/@wdio/mocha-framework/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -7051,9 +7057,9 @@
} }
}, },
"node_modules/@wdio/repl/node_modules/@types/node": { "node_modules/@wdio/repl/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -7076,9 +7082,9 @@
} }
}, },
"node_modules/@wdio/reporter/node_modules/@types/node": { "node_modules/@wdio/reporter/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -7107,9 +7113,9 @@
} }
}, },
"node_modules/@wdio/runner/node_modules/@types/node": { "node_modules/@wdio/runner/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -7156,9 +7162,9 @@
} }
}, },
"node_modules/@wdio/types/node_modules/@types/node": { "node_modules/@wdio/types/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -9005,9 +9011,9 @@
"dev": true "dev": true
}, },
"node_modules/confbox": { "node_modules/confbox": {
"version": "0.1.8", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz",
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA=="
}, },
"node_modules/consola": { "node_modules/consola": {
"version": "3.2.3", "version": "3.2.3",
@ -9052,9 +9058,9 @@
"dev": true "dev": true
}, },
"node_modules/cookie": { "node_modules/cookie": {
"version": "0.6.0", "version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
@ -9855,9 +9861,9 @@
} }
}, },
"node_modules/deepmerge-ts": { "node_modules/deepmerge-ts": {
"version": "7.1.3", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.3.tgz", "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.1.tgz",
"integrity": "sha512-qCSH6I0INPxd9Y1VtAiLpnYvz5O//6rCfJXKk0z66Up9/VOSr+1yS8XSKA5IWRxjocFGlzPyaZYe+jxq7OOLtQ==", "integrity": "sha512-M27OAbyR/XgJujhAd6ZlYvZGzejbzvGPSZWwuzezPCdKLT9VMtK0kpRNDc5LeUDYqFN3e254gWG1yKpjidCtow==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"
@ -10272,9 +10278,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.33", "version": "1.5.32",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz",
"integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", "integrity": "sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==",
"dev": true "dev": true
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
@ -11032,16 +11038,16 @@
"dev": true "dev": true
}, },
"node_modules/eslint-plugin-wc": { "node_modules/eslint-plugin-wc": {
"version": "2.2.0", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.1.1.tgz",
"integrity": "sha512-kjPp+aXz23fOl0JZJOJS+6adwhEv98KjZ2FJqWpc4vtmk4Oenz/JJmmNZrGSARgtyR0BLIF/kVWC6GSlHA+5MA==", "integrity": "sha512-GfJo05ZgWfwAFbW6Gkf+9CMOIU6fmbd3b4nm+PKESHgUdUTmi7vawlELCrzOhdiQjXUPZxDfFIVxYt9D/v/GdQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"is-valid-element-name": "^1.0.0", "is-valid-element-name": "^1.0.0",
"js-levenshtein-esm": "^1.2.0" "js-levenshtein-esm": "^1.2.0"
}, },
"peerDependencies": { "peerDependencies": {
"eslint": ">=8.40.0" "eslint": ">=5"
} }
}, },
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
@ -11405,9 +11411,9 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.21.0", "version": "4.21.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
@ -11415,7 +11421,7 @@
"body-parser": "1.20.3", "body-parser": "1.20.3",
"content-disposition": "0.5.4", "content-disposition": "0.5.4",
"content-type": "~1.0.4", "content-type": "~1.0.4",
"cookie": "0.6.0", "cookie": "0.7.1",
"cookie-signature": "1.0.6", "cookie-signature": "1.0.6",
"debug": "2.6.9", "debug": "2.6.9",
"depd": "2.0.0", "depd": "2.0.0",
@ -14293,9 +14299,9 @@
} }
}, },
"node_modules/knip": { "node_modules/knip": {
"version": "5.33.1", "version": "5.31.0",
"resolved": "https://registry.npmjs.org/knip/-/knip-5.33.1.tgz", "resolved": "https://registry.npmjs.org/knip/-/knip-5.31.0.tgz",
"integrity": "sha512-SeuH+6IcDNNFRdVsi2uGnO6gsSDlx1V+TcQkKnzciF2Z7QHHasKseGUf9GMNVm3bSCKDeqaKPMp0F6BOiKuYRA==", "integrity": "sha512-4hR+qHx/id7mniCWWUqA4MXwGjYFN75xv3qLmEkl9Hm6eCKAhv0wGP0CyrXKUYxVyDplJQsqQaAlsjuRKYsdPA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -14317,7 +14323,7 @@
"easy-table": "1.2.0", "easy-table": "1.2.0",
"enhanced-resolve": "^5.17.1", "enhanced-resolve": "^5.17.1",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"jiti": "^2.3.3", "jiti": "^2.1.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
@ -14342,9 +14348,9 @@
} }
}, },
"node_modules/knip/node_modules/jiti": { "node_modules/knip/node_modules/jiti": {
"version": "2.3.3", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.3.3.tgz", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.2.1.tgz",
"integrity": "sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==", "integrity": "sha512-weIl/Bv3G0J3UKamLxEA2G+FfQ33Z1ZkQJGPjKFV21zQdKWu2Pi6o4elpj2uEl5XdFJZ9xzn1fsanWTFSt45zw==",
"dev": true, "dev": true,
"bin": { "bin": {
"jiti": "lib/jiti-cli.mjs" "jiti": "lib/jiti-cli.mjs"
@ -14489,9 +14495,9 @@
"dev": true "dev": true
}, },
"node_modules/lit": { "node_modules/lit": {
"version": "3.2.1", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz",
"integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==",
"dependencies": { "dependencies": {
"@lit/reactive-element": "^2.0.4", "@lit/reactive-element": "^2.0.4",
"lit-element": "^4.1.0", "lit-element": "^4.1.0",
@ -14525,9 +14531,9 @@
"dev": true "dev": true
}, },
"node_modules/lit-element": { "node_modules/lit-element": {
"version": "4.1.1", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz",
"integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==",
"dependencies": { "dependencies": {
"@lit-labs/ssr-dom-shim": "^1.2.0", "@lit-labs/ssr-dom-shim": "^1.2.0",
"@lit/reactive-element": "^2.0.4", "@lit/reactive-element": "^2.0.4",
@ -14535,9 +14541,9 @@
} }
}, },
"node_modules/lit-html": { "node_modules/lit-html": {
"version": "3.2.1", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz",
"integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==",
"dependencies": { "dependencies": {
"@types/trusted-types": "^2.0.2" "@types/trusted-types": "^2.0.2"
} }
@ -15201,14 +15207,14 @@
"optional": true "optional": true
}, },
"node_modules/mlly": { "node_modules/mlly": {
"version": "1.7.2", "version": "1.7.1",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz",
"integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
"dependencies": { "dependencies": {
"acorn": "^8.12.1", "acorn": "^8.11.3",
"pathe": "^1.1.2", "pathe": "^1.1.2",
"pkg-types": "^1.2.0", "pkg-types": "^1.1.1",
"ufo": "^1.5.4" "ufo": "^1.5.3"
} }
}, },
"node_modules/mocha": { "node_modules/mocha": {
@ -16586,9 +16592,9 @@
"dev": true "dev": true
}, },
"node_modules/package-manager-detector": { "node_modules/package-manager-detector": {
"version": "0.2.1", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.1.tgz", "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz",
"integrity": "sha512-/hVW2fZvAdEas+wyKh0SnlZ2mx0NIa1+j11YaQkogEJkcMErbwchHCuo8z7lEtajZJQZ6rgZNVTWMVVd71Bjng==" "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog=="
}, },
"node_modules/pako": { "node_modules/pako": {
"version": "1.0.11", "version": "1.0.11",
@ -16900,12 +16906,12 @@
} }
}, },
"node_modules/pkg-types": { "node_modules/pkg-types": {
"version": "1.2.1", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz",
"integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==",
"dependencies": { "dependencies": {
"confbox": "^0.1.8", "confbox": "^0.1.7",
"mlly": "^1.7.2", "mlly": "^1.7.1",
"pathe": "^1.1.2" "pathe": "^1.1.2"
} }
}, },
@ -19538,11 +19544,12 @@
} }
}, },
"node_modules/swagger-client": { "node_modules/swagger-client": {
"version": "3.29.4", "version": "3.31.0",
"resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.29.4.tgz", "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.31.0.tgz",
"integrity": "sha512-Me8tdPyRAQbnwNBCZ0BpG0vyci9e+FW6YV3+c6/x8SwPmLpslpFNXoT4PtVApf1CVSvV7Sc7Bfb4DPgpEqBdHw==", "integrity": "sha512-hVYift5XB8nOgNJVl6cbNtVTVPT2Fdx2wCOcIvuAFcyq0Mwe6+70ezoZ5WfiaIAzzwWfq72jyaLeg8TViGNSmw==",
"dependencies": { "dependencies": {
"@babel/runtime-corejs3": "^7.22.15", "@babel/runtime-corejs3": "^7.22.15",
"@scarf/scarf": "=1.4.0",
"@swagger-api/apidom-core": ">=1.0.0-alpha.9 <1.0.0-beta.0", "@swagger-api/apidom-core": ">=1.0.0-alpha.9 <1.0.0-beta.0",
"@swagger-api/apidom-error": ">=1.0.0-alpha.9 <1.0.0-beta.0", "@swagger-api/apidom-error": ">=1.0.0-alpha.9 <1.0.0-beta.0",
"@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.9 <1.0.0-beta.0", "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.9 <1.0.0-beta.0",
@ -20646,14 +20653,14 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.8.1", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.8.1.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.8.0.tgz",
"integrity": "sha512-R0dsXFt6t4SAFjUSKFjMh4pXDtq04SsFKCVGDP3ZOzNP7itF0jBcZYU4fMsZr4y7O7V7Nc751dDeESbe4PbQMQ==", "integrity": "sha512-BjIT/VwJ8+0rVO01ZQ2ZVnjE1svFBiRczcpr1t1Yxt7sT25VSbPfrJtDsQ8uQTy2pilX5nI9gwxhUyLULNentw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.8.1", "@typescript-eslint/eslint-plugin": "8.8.0",
"@typescript-eslint/parser": "8.8.1", "@typescript-eslint/parser": "8.8.0",
"@typescript-eslint/utils": "8.8.1" "@typescript-eslint/utils": "8.8.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -20911,17 +20918,17 @@
"integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==" "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg=="
}, },
"node_modules/untyped": { "node_modules/untyped": {
"version": "1.5.1", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/untyped/-/untyped-1.5.1.tgz", "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.5.0.tgz",
"integrity": "sha512-reBOnkJBFfBZ8pCKaeHgfZLcehXtM6UTxc+vqs1JvCps0c4amLNp3fhdGBZwYp+VLyoY9n3X5KOP7lCyWBUX9A==", "integrity": "sha512-o2Vjmn2dal08BzCcINxSmWuAteReUUiXseii5VRhmxyLF0b21K0iKZQ9fMYK7RWspVkY+0saqaVQNq4roe3Efg==",
"dev": true, "dev": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@babel/core": "^7.25.7", "@babel/core": "^7.25.2",
"@babel/standalone": "^7.25.7", "@babel/standalone": "^7.25.6",
"@babel/types": "^7.25.7", "@babel/types": "^7.25.6",
"defu": "^6.1.4", "defu": "^6.1.4",
"jiti": "^2.3.1", "jiti": "^2.0.0",
"mri": "^1.2.0", "mri": "^1.2.0",
"scule": "^1.3.0" "scule": "^1.3.0"
}, },
@ -20945,9 +20952,9 @@
} }
}, },
"node_modules/untyped/node_modules/jiti": { "node_modules/untyped/node_modules/jiti": {
"version": "2.3.3", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.3.3.tgz", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.2.1.tgz",
"integrity": "sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==", "integrity": "sha512-weIl/Bv3G0J3UKamLxEA2G+FfQ33Z1ZkQJGPjKFV21zQdKWu2Pi6o4elpj2uEl5XdFJZ9xzn1fsanWTFSt45zw==",
"dev": true, "dev": true,
"optional": true, "optional": true,
"bin": { "bin": {
@ -21881,9 +21888,9 @@
} }
}, },
"node_modules/webdriver/node_modules/@types/node": { "node_modules/webdriver/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -21936,9 +21943,9 @@
} }
}, },
"node_modules/webdriverio/node_modules/@types/node": { "node_modules/webdriverio/node_modules/@types/node": {
"version": "20.16.11", "version": "20.16.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
"integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"

View File

@ -11,7 +11,7 @@
"@floating-ui/dom": "^1.6.11", "@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7", "@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0", "@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2024.10.0-1730331602", "@goauthentik/api": "^2024.10.1-1731327664",
"@lit-labs/ssr": "^3.2.2", "@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2", "@lit/localize": "^0.12.2",

View File

@ -71,7 +71,6 @@ export class ApplicationWizardApplicationDetails extends WithBrandConfig(BasePro
flowType=${FlowsInstancesListDesignationEnum.Invalidation} flowType=${FlowsInstancesListDesignationEnum.Invalidation}
.currentFlow=${provider?.invalidationFlow} .currentFlow=${provider?.invalidationFlow}
.brandFlow=${this.brand.flowInvalidation} .brandFlow=${this.brand.flowInvalidation}
defaultFlowSlug="default-invalidation-flow"
required required
></ak-branded-flow-search> ></ak-branded-flow-search>
<p class="pf-c-form__helper-text">${msg("Flow used for unbinding users.")}</p> <p class="pf-c-form__helper-text">${msg("Flow used for unbinding users.")}</p>

View File

@ -86,7 +86,7 @@ export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(Bas
<ak-flow-search <ak-flow-search
flowType=${FlowsInstancesListDesignationEnum.Invalidation} flowType=${FlowsInstancesListDesignationEnum.Invalidation}
.currentFlow=${provider?.invalidationFlow} .currentFlow=${provider?.invalidationFlow}
defaultFlowSlug="default-invalidation-flow" defaultFlowSlug="default-provider-invalidation-flow"
required required
></ak-flow-search> ></ak-flow-search>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">

View File

@ -157,7 +157,6 @@ export class LDAPProviderFormPage extends WithBrandConfig(BaseProviderForm<LDAPP
flowType=${FlowsInstancesListDesignationEnum.Invalidation} flowType=${FlowsInstancesListDesignationEnum.Invalidation}
.currentFlow=${this.instance?.invalidationFlow} .currentFlow=${this.instance?.invalidationFlow}
.brandFlow=${this.brand.flowInvalidation} .brandFlow=${this.brand.flowInvalidation}
defaultFlowSlug="default-invalidation-flow"
required required
></ak-branded-flow-search> ></ak-branded-flow-search>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">

View File

@ -176,7 +176,7 @@ export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<Rad
<ak-flow-search <ak-flow-search
flowType=${FlowsInstancesListDesignationEnum.Invalidation} flowType=${FlowsInstancesListDesignationEnum.Invalidation}
.currentFlow=${this.instance?.invalidationFlow} .currentFlow=${this.instance?.invalidationFlow}
defaultFlowSlug="default-invalidation-flow" defaultFlowSlug="default-provider-invalidation-flow"
required required
></ak-flow-search> ></ak-flow-search>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">

View File

@ -2,6 +2,7 @@ import { BaseStageForm } from "@goauthentik/admin/stages/BaseStageForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-number-input"; import "@goauthentik/components/ak-number-input";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
@ -80,6 +81,15 @@ export class CaptchaStageForm extends BaseStageForm<CaptchaStage> {
)} )}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-switch-input
name="interactive"
label=${msg("Interactive")}
?checked="${this.instance?.interactive}"
help=${msg(
"Enable this flag if the configured captcha requires User-interaction. Required for reCAPTCHA v2, hCaptcha and Cloudflare Turnstile.",
)}
>
</ak-switch-input>
<ak-number-input <ak-number-input
label=${msg("Score minimum threshold")} label=${msg("Score minimum threshold")}
required required

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger"; export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress"; export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current"; export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2024.10.0"; export const VERSION = "2024.10.2";
export const TITLE_DEFAULT = "authentik"; export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";"; export const ROUTE_SEPARATOR = ";";

View File

@ -10,10 +10,14 @@ export const DOM_PURIFY_STRICT: DOMPurify.Config = {
ALLOWED_TAGS: ["#text"], ALLOWED_TAGS: ["#text"],
}; };
export async function renderStatic(input: TemplateResult): Promise<string> {
return await collectResult(render(input));
}
export function purify(input: TemplateResult): TemplateResult { export function purify(input: TemplateResult): TemplateResult {
return html`${until( return html`${until(
(async () => { (async () => {
const rendered = await collectResult(render(input)); const rendered = await renderStatic(input);
const purified = DOMPurify.sanitize(rendered); const purified = DOMPurify.sanitize(rendered);
return html`${unsafeHTML(purified)}`; return html`${unsafeHTML(purified)}`;
})(), })(),

View File

@ -44,12 +44,6 @@ export class Alert extends AKElement implements IAlert {
@property({ type: Boolean }) @property({ type: Boolean })
inline = false; inline = false;
/**
* When true, removes the background color and status line; the text and icon are retained and
* colored.
*
* @attr
*/
@property({ type: Boolean }) @property({ type: Boolean })
plain = false; plain = false;

View File

@ -6,14 +6,6 @@ import { customElement } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
/**
* @class Divider
* @element ak-divider
*
* Divider is a horizontal rule, an in-page element to separate displayed items.
*
* @slot - HTML to display in-line in the middle of the horizontal rule.
*/
@customElement("ak-divider") @customElement("ak-divider")
export class Divider extends AKElement { export class Divider extends AKElement {
static get styles() { static get styles() {

View File

@ -15,38 +15,14 @@ export interface IExpand {
textClosed?: string; textClosed?: string;
} }
/**
* @class Expand
* @element ak-expand
*
* An `ak-expand` is used to hide cluttering details that a user may wish to reveal, such as the raw
* details of an alert or event.
*
* slot - The contents to be hidden or displayed.
*/
@customElement("ak-expand") @customElement("ak-expand")
export class Expand extends AKElement implements IExpand { export class Expand extends AKElement implements IExpand {
/** @property({ type: Boolean })
* The state of the expanded content
*
* @attr
*/
@property({ type: Boolean, reflect: true })
expanded = false; expanded = false;
/**
* The text to display next to the open/close control when the accordion is open.
*
* @attr
*/
@property({ type: String, attribute: "text-open" }) @property({ type: String, attribute: "text-open" })
textOpen = msg("Show less"); textOpen = msg("Show less");
/**
* The text to display next to the open/close control when the accordion is closed.
*
* @attr
*/
@property({ type: String, attribute: "text-closed" }) @property({ type: String, attribute: "text-closed" })
textClosed = msg("Show more"); textClosed = msg("Show more");

View File

@ -12,23 +12,9 @@ export interface ILoadingOverlay {
topmost?: boolean; topmost?: boolean;
} }
/**
* @class LoadingOverlay
* @element ak-loading-overlay
*
* The LoadingOverlay is meant to cover the container element completely, hiding the content behind
* a dimming filter, while content loads.
*
* @slot - [Optional] message content to display while the overlay is visible.
*/
@customElement("ak-loading-overlay") @customElement("ak-loading-overlay")
export class LoadingOverlay extends AKElement implements ILoadingOverlay { export class LoadingOverlay extends AKElement implements ILoadingOverlay {
/** // Do not camelize: https://www.merriam-webster.com/dictionary/topmost
* When true, forces the overlay onto the top layer of the display stack.
* Do not camelize: https://www.merriam-webster.com/dictionary/topmost
*
* @attr
*/
@property({ type: Boolean, attribute: "topmost" }) @property({ type: Boolean, attribute: "topmost" })
topmost = false; topmost = false;

View File

@ -4,9 +4,9 @@ import { Meta } from "@storybook/web-components";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import "./ak-action-button"; import "./ak-action-button";
import { ActionButton } from "./ak-action-button"; import AKActionButton from "./ak-action-button";
const metadata: Meta<ActionButton> = { const metadata: Meta<AKActionButton> = {
title: "Elements / <ak-action-button>", title: "Elements / <ak-action-button>",
component: "ak-action-button", component: "ak-action-button",
parameters: { parameters: {

View File

@ -1,14 +1,9 @@
import { MessageLevel } from "@goauthentik/common/messages"; import { MessageLevel } from "@goauthentik/common/messages";
import { import { BaseTaskButton } from "@goauthentik/elements/buttons/SpinnerButton/BaseTaskButton";
BaseTaskButton,
type IBaseTaskButton,
} from "@goauthentik/elements/buttons/SpinnerButton/BaseTaskButton";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer"; import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
type IActionButton = IBaseTaskButton & { apiRequest: () => Promise<unknown> };
/** /**
* A button associated with an event handler for loading data. Takes an asynchronous function as its * A button associated with an event handler for loading data. Takes an asynchronous function as its
* only property. * only property.
@ -24,7 +19,7 @@ type IActionButton = IBaseTaskButton & { apiRequest: () => Promise<unknown> };
*/ */
@customElement("ak-action-button") @customElement("ak-action-button")
export class ActionButton extends BaseTaskButton implements IActionButton { export class ActionButton extends BaseTaskButton {
/** /**
* The command to run when the button is pressed. Must return a promise. If the promise is a * The command to run when the button is pressed. Must return a promise. If the promise is a
* reject or throw, we process the content of the promise and deliver it to the Notification * reject or throw, we process the content of the promise and deliver it to the Notification
@ -32,6 +27,7 @@ export class ActionButton extends BaseTaskButton implements IActionButton {
* *
* @attr * @attr
*/ */
@property({ attribute: false }) @property({ attribute: false })
apiRequest: () => Promise<unknown> = () => { apiRequest: () => Promise<unknown> = () => {
throw new Error(); throw new Error();

View File

@ -36,10 +36,6 @@ const StatusMap = new Map<TaskStatus, string>([
const SPINNER_TIMEOUT = 1000 * 1.5; // milliseconds const SPINNER_TIMEOUT = 1000 * 1.5; // milliseconds
export interface IBaseTaskButton {
disabled?: boolean;
}
/** /**
* BaseTaskButton * BaseTaskButton
* *
@ -50,6 +46,7 @@ export interface IBaseTaskButton {
* `onFailure` call their `super.` equivalents. * `onFailure` call their `super.` equivalents.
* *
*/ */
export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) { export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
eventPrefix = "ak-button"; eventPrefix = "ak-button";

View File

@ -1,7 +1,7 @@
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { property } from "lit/decorators.js"; import { property } from "lit/decorators.js";
import { BaseTaskButton, type IBaseTaskButton } from "./BaseTaskButton"; import { BaseTaskButton } from "./BaseTaskButton";
/** /**
* A button associated with an event handler for loading data. Takes an asynchronous function as its * A button associated with an event handler for loading data. Takes an asynchronous function as its
@ -17,10 +17,8 @@ import { BaseTaskButton, type IBaseTaskButton } from "./BaseTaskButton";
* @fires ak-button-reset - When the button is reset after the async process completes * @fires ak-button-reset - When the button is reset after the async process completes
*/ */
type ISpinnerButton = IBaseTaskButton & { callAction: () => Promise<unknown> };
@customElement("ak-spinner-button") @customElement("ak-spinner-button")
export class SpinnerButton extends BaseTaskButton implements ISpinnerButton { export class SpinnerButton extends BaseTaskButton {
/** /**
* The command to run when the button is pressed. Must return a promise. We don't do anything * The command to run when the button is pressed. Must return a promise. We don't do anything
* with that promise other than check if it's a resolve or reject, and rethrow the event after. * with that promise other than check if it's a resolve or reject, and rethrow the event after.

View File

@ -107,7 +107,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseDeviceStage<
?loading="${this.authenticating}" ?loading="${this.authenticating}"
header=${this.authenticating header=${this.authenticating
? msg("Authenticating...") ? msg("Authenticating...")
: this.errorMessage || msg("Failed to authenticate")} : this.errorMessage || msg("Loading")}
icon="fa-times" icon="fa-times"
> >
</ak-empty-state> </ak-empty-state>

View File

@ -10,7 +10,7 @@ import "../../../stories/flow-interface";
import "./CaptchaStage"; import "./CaptchaStage";
export default { export default {
title: "Flow / Stages / CaptchaStage", title: "Flow / Stages / Captcha",
}; };
export const LoadingNoChallenge = () => { export const LoadingNoChallenge = () => {
@ -25,92 +25,60 @@ export const LoadingNoChallenge = () => {
</ak-storybook-interface>`; </ak-storybook-interface>`;
}; };
export const ChallengeGoogleReCaptcha: StoryObj = { function captchaFactory(challenge: CaptchaChallenge): StoryObj {
render: ({ theme, challenge }) => { return {
return html`<ak-storybook-interface theme=${theme}> render: ({ theme, challenge }) => {
<div class="pf-c-login"> return html`<ak-storybook-interface theme=${theme}>
<div class="pf-c-login__container"> <div class="pf-c-login">
<div class="pf-c-login__main"> <div class="pf-c-login__container">
<ak-stage-captcha .challenge=${challenge}></ak-stage-captcha> <div class="pf-c-login__main">
</div> <ak-stage-captcha .challenge=${challenge}></ak-stage-captcha>
</div></div </div>
></ak-storybook-interface>`; </div></div
}, ></ak-storybook-interface>`;
args: { },
theme: "automatic", args: {
challenge: { theme: "automatic",
pendingUser: "foo", challenge: challenge,
pendingUserAvatar: "https://picsum.photos/64", },
jsUrl: "https://www.google.com/recaptcha/api.js", argTypes: {
siteKey: "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI", theme: {
} as CaptchaChallenge, options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
}, control: {
argTypes: { type: "select",
theme: { },
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
control: {
type: "select",
}, },
}, },
}, };
}; }
export const ChallengeHCaptcha: StoryObj = { export const ChallengeHCaptcha = captchaFactory({
render: ({ theme, challenge }) => { pendingUser: "foo",
return html`<ak-storybook-interface theme=${theme}> pendingUserAvatar: "https://picsum.photos/64",
<div class="pf-c-login"> jsUrl: "https://js.hcaptcha.com/1/api.js",
<div class="pf-c-login__container"> siteKey: "10000000-ffff-ffff-ffff-000000000001",
<div class="pf-c-login__main"> interactive: true,
<ak-stage-captcha .challenge=${challenge}></ak-stage-captcha> } as CaptchaChallenge);
</div>
</div></div
></ak-storybook-interface>`;
},
args: {
theme: "automatic",
challenge: {
pendingUser: "foo",
pendingUserAvatar: "https://picsum.photos/64",
jsUrl: "https://js.hcaptcha.com/1/api.js",
siteKey: "10000000-ffff-ffff-ffff-000000000001",
} as CaptchaChallenge,
},
argTypes: {
theme: {
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
control: {
type: "select",
},
},
},
};
export const ChallengeTurnstile: StoryObj = { // https://developers.cloudflare.com/turnstile/troubleshooting/testing/
render: ({ theme, challenge }) => { export const ChallengeTurnstileVisible = captchaFactory({
return html`<ak-storybook-interface theme=${theme}> pendingUser: "foo",
<div class="pf-c-login"> pendingUserAvatar: "https://picsum.photos/64",
<div class="pf-c-login__container"> jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js",
<div class="pf-c-login__main"> siteKey: "1x00000000000000000000AA",
<ak-stage-captcha .challenge=${challenge}></ak-stage-captcha> interactive: true,
</div> } as CaptchaChallenge);
</div></div export const ChallengeTurnstileInvisible = captchaFactory({
></ak-storybook-interface>`; pendingUser: "foo",
}, pendingUserAvatar: "https://picsum.photos/64",
args: { jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js",
theme: "automatic", siteKey: "1x00000000000000000000BB",
challenge: { interactive: true,
pendingUser: "foo", } as CaptchaChallenge);
pendingUserAvatar: "https://picsum.photos/64", export const ChallengeTurnstileForce = captchaFactory({
jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js", pendingUser: "foo",
siteKey: "1x00000000000000000000BB", pendingUserAvatar: "https://picsum.photos/64",
} as CaptchaChallenge, jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js",
}, siteKey: "3x00000000000000000000FF",
argTypes: { interactive: true,
theme: { } as CaptchaChallenge);
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
control: {
type: "select",
},
},
},
};

View File

@ -1,16 +1,17 @@
///<reference types="@hcaptcha/types"/> ///<reference types="@hcaptcha/types"/>
import { renderStatic } from "@goauthentik/common/purify";
import "@goauthentik/elements/EmptyState"; import "@goauthentik/elements/EmptyState";
import "@goauthentik/elements/forms/FormElement"; import "@goauthentik/elements/forms/FormElement";
import { randomId } from "@goauthentik/elements/utils/randomId";
import "@goauthentik/flow/FormStatic"; import "@goauthentik/flow/FormStatic";
import { BaseStage } from "@goauthentik/flow/stages/base"; import { BaseStage } from "@goauthentik/flow/stages/base";
import type { TurnstileObject } from "turnstile-types"; import type { TurnstileObject } from "turnstile-types";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, PropertyValues, html } from "lit"; import { CSSResult, PropertyValues, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css"; import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css"; import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFLogin from "@patternfly/patternfly/components/Login/login.css"; import PFLogin from "@patternfly/patternfly/components/Login/login.css";
@ -24,12 +25,22 @@ interface TurnstileWindow extends Window {
} }
type TokenHandler = (token: string) => void; type TokenHandler = (token: string) => void;
const captchaContainerID = "captcha-container";
@customElement("ak-stage-captcha") @customElement("ak-stage-captcha")
export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeResponseRequest> { export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeResponseRequest> {
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton]; return [
PFBase,
PFLogin,
PFForm,
PFFormControl,
PFTitle,
css`
iframe {
width: 100%;
height: 73px; /* tmp */
}
`,
];
} }
handlers = [this.handleGReCaptcha, this.handleHCaptcha, this.handleTurnstile]; handlers = [this.handleGReCaptcha, this.handleHCaptcha, this.handleTurnstile];
@ -38,14 +49,17 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
error?: string; error?: string;
@state() @state()
captchaInteractive: boolean = true; captchaFrame: HTMLIFrameElement;
@state() @state()
captchaContainer: HTMLDivElement; captchaDocumentContainer: HTMLDivElement;
@state() @state()
scriptElement?: HTMLScriptElement; scriptElement?: HTMLScriptElement;
@property({ type: Boolean })
embedded = false;
@property() @property()
onTokenChange: TokenHandler = (token: string) => { onTokenChange: TokenHandler = (token: string) => {
this.host.submit({ component: "ak-stage-captcha", token }); this.host.submit({ component: "ak-stage-captcha", token });
@ -53,8 +67,70 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
constructor() { constructor() {
super(); super();
this.captchaContainer = document.createElement("div"); this.captchaFrame = document.createElement("iframe");
this.captchaContainer.id = captchaContainerID; this.captchaFrame.src = "about:blank";
this.captchaFrame.id = `ak-captcha-${randomId()}`;
this.captchaDocumentContainer = document.createElement("div");
this.captchaDocumentContainer.id = `ak-captcha-${randomId()}`;
this.messageCallback = this.messageCallback.bind(this);
}
connectedCallback(): void {
super.connectedCallback();
window.addEventListener("message", this.messageCallback);
}
disconnectedCallback(): void {
super.disconnectedCallback();
window.removeEventListener("message", this.messageCallback);
if (!this.challenge.interactive) {
document.removeChild(this.captchaDocumentContainer);
}
}
messageCallback(
ev: MessageEvent<{
source?: string;
context?: string;
message: string;
token: string;
}>,
) {
const msg = ev.data;
if (msg.source !== "goauthentik.io" || msg.context !== "flow-executor") {
return;
}
if (msg.message !== "captcha") {
return;
}
this.onTokenChange(msg.token);
}
async renderFrame(captchaElement: TemplateResult) {
this.captchaFrame.contentWindow?.document.open();
this.captchaFrame.contentWindow?.document.write(
await renderStatic(
html`<!doctype html>
<html>
<body style="display:flex;flex-direction:row;justify-content:center;">
${captchaElement}
<script src=${this.challenge.jsUrl}></script>
<script>
function callback(token) {
window.parent.postMessage({
message: "captcha",
source: "goauthentik.io",
context: "flow-executor",
token: token,
});
}
</script>
</body>
</html>`,
),
);
this.captchaFrame.contentWindow?.document.close();
} }
updated(changedProperties: PropertyValues<this>) { updated(changedProperties: PropertyValues<this>) {
@ -64,15 +140,15 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
this.scriptElement.async = true; this.scriptElement.async = true;
this.scriptElement.defer = true; this.scriptElement.defer = true;
this.scriptElement.dataset.akCaptchaScript = "true"; this.scriptElement.dataset.akCaptchaScript = "true";
this.scriptElement.onload = () => { this.scriptElement.onload = async () => {
console.debug("authentik/stages/captcha: script loaded"); console.debug("authentik/stages/captcha: script loaded");
let found = false; let found = false;
let lastError = undefined; let lastError = undefined;
this.handlers.forEach((handler) => { this.handlers.forEach(async (handler) => {
let handlerFound = false; let handlerFound = false;
try { try {
console.debug(`authentik/stages/captcha[${handler.name}]: trying handler`); console.debug(`authentik/stages/captcha[${handler.name}]: trying handler`);
handlerFound = handler.apply(this); handlerFound = await handler.apply(this);
if (handlerFound) { if (handlerFound) {
console.debug( console.debug(
`authentik/stages/captcha[${handler.name}]: handler succeeded`, `authentik/stages/captcha[${handler.name}]: handler succeeded`,
@ -96,51 +172,79 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
.querySelectorAll("[data-ak-captcha-script=true]") .querySelectorAll("[data-ak-captcha-script=true]")
.forEach((el) => el.remove()); .forEach((el) => el.remove());
document.head.appendChild(this.scriptElement); document.head.appendChild(this.scriptElement);
if (!this.challenge.interactive) {
document.appendChild(this.captchaDocumentContainer);
}
} }
} }
handleGReCaptcha(): boolean { async handleGReCaptcha(): Promise<boolean> {
if (!Object.hasOwn(window, "grecaptcha")) { if (!Object.hasOwn(window, "grecaptcha")) {
return false; return false;
} }
this.captchaInteractive = false; if (this.challenge.interactive) {
document.body.appendChild(this.captchaContainer); this.renderFrame(
grecaptcha.ready(() => { html`<div
const captchaId = grecaptcha.render(this.captchaContainer, { class="g-recaptcha"
data-sitekey="${this.challenge.siteKey}"
data-callback="callback"
></div>`,
);
} else {
grecaptcha.ready(() => {
const captchaId = grecaptcha.render(this.captchaDocumentContainer, {
sitekey: this.challenge.siteKey,
callback: this.onTokenChange,
size: "invisible",
});
grecaptcha.execute(captchaId);
});
}
return true;
}
async handleHCaptcha(): Promise<boolean> {
if (!Object.hasOwn(window, "hcaptcha")) {
return false;
}
if (this.challenge.interactive) {
this.renderFrame(
html`<div
class="h-captcha"
data-sitekey="${this.challenge.siteKey}"
data-theme="${this.activeTheme ? this.activeTheme : "light"}"
data-callback="callback"
></div> `,
);
} else {
const captchaId = hcaptcha.render(this.captchaDocumentContainer, {
sitekey: this.challenge.siteKey, sitekey: this.challenge.siteKey,
callback: this.onTokenChange, callback: this.onTokenChange,
size: "invisible", size: "invisible",
}); });
grecaptcha.execute(captchaId); hcaptcha.execute(captchaId);
});
return true;
}
handleHCaptcha(): boolean {
if (!Object.hasOwn(window, "hcaptcha")) {
return false;
} }
this.captchaInteractive = false;
document.body.appendChild(this.captchaContainer);
const captchaId = hcaptcha.render(this.captchaContainer, {
sitekey: this.challenge.siteKey,
callback: this.onTokenChange,
size: "invisible",
});
hcaptcha.execute(captchaId);
return true; return true;
} }
handleTurnstile(): boolean { async handleTurnstile(): Promise<boolean> {
if (!Object.hasOwn(window, "turnstile")) { if (!Object.hasOwn(window, "turnstile")) {
return false; return false;
} }
this.captchaInteractive = false; if (this.challenge.interactive) {
document.body.appendChild(this.captchaContainer); this.renderFrame(
(window as unknown as TurnstileWindow).turnstile.render(`#${captchaContainerID}`, { html`<div
sitekey: this.challenge.siteKey, class="cf-turnstile"
callback: this.onTokenChange, data-sitekey="${this.challenge.siteKey}"
}); data-callback="callback"
></div>`,
);
} else {
(window as unknown as TurnstileWindow).turnstile.render(this.captchaDocumentContainer, {
sitekey: this.challenge.siteKey,
callback: this.onTokenChange,
});
}
return true; return true;
} }
@ -148,13 +252,19 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
if (this.error) { if (this.error) {
return html`<ak-empty-state icon="fa-times" header=${this.error}> </ak-empty-state>`; return html`<ak-empty-state icon="fa-times" header=${this.error}> </ak-empty-state>`;
} }
if (this.captchaInteractive) { if (this.challenge.interactive) {
return html`${this.captchaContainer}`; return html`${this.captchaFrame}`;
} }
return html`<ak-empty-state loading header=${msg("Verifying...")}></ak-empty-state>`; return html`<ak-empty-state loading header=${msg("Verifying...")}></ak-empty-state>`;
} }
render() { render() {
if (this.embedded) {
if (!this.challenge.interactive) {
return html``;
}
return this.renderBody();
}
if (!this.challenge) { if (!this.challenge) {
return html`<ak-empty-state loading> </ak-empty-state>`; return html`<ak-empty-state loading> </ak-empty-state>`;
} }

View File

@ -0,0 +1,87 @@
import type { StoryObj } from "@storybook/web-components";
import { html } from "lit";
import "@patternfly/patternfly/components/Login/login.css";
import { FlowDesignationEnum, IdentificationChallenge, UiThemeEnum } from "@goauthentik/api";
import "../../../stories/flow-interface";
import "./IdentificationStage";
export default {
title: "Flow / Stages / Identification",
};
export const LoadingNoChallenge = () => {
return html`<ak-storybook-interface theme=${UiThemeEnum.Dark}>
<div class="pf-c-login">
<div class="pf-c-login__container">
<div class="pf-c-login__main">
<ak-stage-identification></ak-stage-identification>
</div>
</div>
</div>
</ak-storybook-interface>`;
};
function identificationFactory(challenge: IdentificationChallenge): StoryObj {
return {
render: ({ theme, challenge }) => {
return html`<ak-storybook-interface theme=${theme}>
<div class="pf-c-login">
<div class="pf-c-login__container">
<div class="pf-c-login__main">
<ak-stage-identification
.challenge=${challenge}
></ak-stage-identification>
</div>
</div></div
></ak-storybook-interface>`;
},
args: {
theme: "automatic",
challenge: challenge,
},
argTypes: {
theme: {
options: [UiThemeEnum.Automatic, UiThemeEnum.Light, UiThemeEnum.Dark],
control: {
type: "select",
},
},
},
};
}
export const ChallengeDefault = identificationFactory({
userFields: ["username"],
passwordFields: false,
flowDesignation: FlowDesignationEnum.Authentication,
primaryAction: "Login",
showSourceLabels: false,
// jsUrl: "https://js.hcaptcha.com/1/api.js",
// siteKey: "10000000-ffff-ffff-ffff-000000000001",
// interactive: true,
});
// https://developers.cloudflare.com/turnstile/troubleshooting/testing/
export const ChallengeCaptchaTurnstileVisible = identificationFactory({
userFields: ["username"],
passwordFields: false,
flowDesignation: FlowDesignationEnum.Authentication,
primaryAction: "Login",
showSourceLabels: false,
flowInfo: {
layout: "stacked",
cancelUrl: "",
title: "Foo",
},
captchaStage: {
pendingUser: "",
pendingUserAvatar: "",
jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js",
siteKey: "1x00000000000000000000AA",
interactive: true,
},
});

View File

@ -282,11 +282,11 @@ export class IdentificationStage extends BaseStage<
? html` ? html`
<input name="captchaToken" type="hidden" .value="${this.captchaToken}" /> <input name="captchaToken" type="hidden" .value="${this.captchaToken}" />
<ak-stage-captcha <ak-stage-captcha
style="visibility: hidden; position:absolute;"
.challenge=${this.challenge.captchaStage} .challenge=${this.challenge.captchaStage}
.onTokenChange=${(token: string) => { .onTokenChange=${(token: string) => {
this.captchaToken = token; this.captchaToken = token;
}} }}
embedded
></ak-stage-captcha> ></ak-stage-captcha>
` `
: nothing} : nothing}

View File

@ -5819,6 +5819,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="sfc31264ef7ff86ef"> <trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
</trans-unit> </trans-unit>
@ -5963,6 +5966,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -7014,18 +7020,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -6084,6 +6084,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="sfc31264ef7ff86ef"> <trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
</trans-unit> </trans-unit>
@ -6228,6 +6231,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -7279,18 +7285,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -5736,6 +5736,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="sfc31264ef7ff86ef"> <trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
</trans-unit> </trans-unit>
@ -5880,6 +5883,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -6931,18 +6937,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -7646,6 +7646,10 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>Pour nginx auth_request ou traefik forwardAuth par domaine racine</target> <target>Pour nginx auth_request ou traefik forwardAuth par domaine racine</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC est en aperçu.</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>Type d'utilisateur pour les utilisateurs nouvellement créés.</target> <target>Type d'utilisateur pour les utilisateurs nouvellement créés.</target>
@ -7838,6 +7842,10 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>Créer un point de terminaison</target> <target>Créer un point de terminaison</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>RAC est en aperçu.</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>Mettre à jour le fournisseur RAC</target> <target>Mettre à jour le fournisseur RAC</target>
@ -9240,18 +9248,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

File diff suppressed because it is too large Load Diff

View File

@ -7616,6 +7616,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>루트 도메인 당 Nginx의 auth_request 또는 Traefik의 forwardAuth 경우</target> <target>루트 도메인 당 Nginx의 auth_request 또는 Traefik의 forwardAuth 경우</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC 는 현재 프리뷰입니다.</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>새로 생성된 사용자에 사용되는 사용자 유형입니다.</target> <target>새로 생성된 사용자에 사용되는 사용자 유형입니다.</target>
@ -7810,6 +7814,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -8846,18 +8853,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -7396,6 +7396,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="sf79f8681e5ffaee2"> <trans-unit id="sf79f8681e5ffaee2">
<source>Assign to new user</source> <source>Assign to new user</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="saabeb4cab074b0b9"> <trans-unit id="saabeb4cab074b0b9">
<source>User Object Permissions</source> <source>User Object Permissions</source>
</trans-unit> </trans-unit>
@ -7483,6 +7486,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -8693,18 +8699,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -7650,6 +7650,10 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>Dla nginx's auth_request lub traefik's forwardAuth dla domeny głównej</target> <target>Dla nginx's auth_request lub traefik's forwardAuth dla domeny głównej</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC jest w fazie zapoznawczej.</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>Typ użytkownika używany dla nowo utworzonych użytkowników.</target> <target>Typ użytkownika używany dla nowo utworzonych użytkowników.</target>
@ -7842,6 +7846,10 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>Utwórz punkt końcowy</target> <target>Utwórz punkt końcowy</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>RAC jest w fazie zapoznawczej.</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>Aktualizuj dostawcę RAC</target> <target>Aktualizuj dostawcę RAC</target>
@ -9110,18 +9118,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -7594,6 +7594,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>Ƒōŕ ńĝĩńx'ś àũţĥ_ŕēǫũēśţ ōŕ ţŕàēƒĩķ'ś ƒōŕŵàŕďÀũţĥ ƥēŕ ŕōōţ ďōḿàĩń</target> <target>Ƒōŕ ńĝĩńx'ś àũţĥ_ŕēǫũēśţ ōŕ ţŕàēƒĩķ'ś ƒōŕŵàŕďÀũţĥ ƥēŕ ŕōōţ ďōḿàĩń</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>ŔßÀĆ ĩś ĩń ƥŕēvĩēŵ.</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>Ũśēŕ ţŷƥē ũśēď ƒōŕ ńēŵĺŷ ćŕēàţēď ũśēŕś.</target> <target>Ũśēŕ ţŷƥē ũśēď ƒōŕ ńēŵĺŷ ćŕēàţēď ũśēŕś.</target>
@ -7786,6 +7790,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>Ćŕēàţē Ēńďƥōĩńţ</target> <target>Ćŕēàţē Ēńďƥōĩńţ</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>ŔÀĆ ĩś ĩń ƥŕēvĩēŵ.</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>Ũƥďàţē ŔÀĆ Ƥŕōvĩďēŕ</target> <target>Ũƥďàţē ŔÀĆ Ƥŕōvĩďēŕ</target>
@ -9150,16 +9158,4 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit> </trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit>
</body></file></xliff> </body></file></xliff>

View File

@ -7649,6 +7649,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>Для nginx's auth_request или traefik's forwardAuth для корневого домена</target> <target>Для nginx's auth_request или traefik's forwardAuth для корневого домена</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC находится в предварительной версии.</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>Тип пользователя, используемый для вновь созданных пользователей.</target> <target>Тип пользователя, используемый для вновь созданных пользователей.</target>
@ -7841,6 +7845,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>Создать конечную точку</target> <target>Создать конечную точку</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>RAC находится в предварительной версии.</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>Обновить RAC провайдера</target> <target>Обновить RAC провайдера</target>
@ -9173,18 +9181,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -5729,6 +5729,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="sfc31264ef7ff86ef"> <trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
</trans-unit> </trans-unit>
@ -5873,6 +5876,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -6924,18 +6930,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -1375,6 +1375,9 @@
<trans-unit id="s9fb28be12e2c6317"> <trans-unit id="s9fb28be12e2c6317">
<source>Superuser</source> <source>Superuser</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="sa1db89262360550b"> <trans-unit id="sa1db89262360550b">
<source>Send us feedback!</source> <source>Send us feedback!</source>
</trans-unit> </trans-unit>
@ -1911,6 +1914,9 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -5863,18 +5869,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit> </trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -7648,6 +7648,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>适用于按根域名配置的 nginx 的 auth_request 或 traefik 的 forwardAuth</target> <target>适用于按根域名配置的 nginx 的 auth_request 或 traefik 的 forwardAuth</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC 目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>新创建用户使用的用户类型。</target> <target>新创建用户使用的用户类型。</target>
@ -7840,6 +7844,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>创建端点</target> <target>创建端点</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>RAC 目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>更新 RAC 提供程序</target> <target>更新 RAC 提供程序</target>
@ -9120,147 +9128,99 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="sbfee780fa0a2c83e"> <trans-unit id="sbfee780fa0a2c83e">
<source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be deleted</source> <source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be deleted</source>
<target>设备类型 <x id="0" equiv-text="${device.verboseName}"/> 无法被删除</target>
</trans-unit> </trans-unit>
<trans-unit id="s336936629cdeb3e5"> <trans-unit id="s336936629cdeb3e5">
<source>Stage used to verify users' browsers using Google Chrome Device Trust. This stage can be used in authentication/authorization flows.</source> <source>Stage used to verify users' browsers using Google Chrome Device Trust. This stage can be used in authentication/authorization flows.</source>
<target>通过 Google Chrome 设备信任来验证用户浏览器的阶段。此阶段可在身份验证/授权流程中使用。</target>
</trans-unit> </trans-unit>
<trans-unit id="s85fe794c71b4ace8"> <trans-unit id="s85fe794c71b4ace8">
<source>Google Verified Access API</source> <source>Google Verified Access API</source>
<target>Google Verified Access API</target>
</trans-unit> </trans-unit>
<trans-unit id="s013620384af7c8b4"> <trans-unit id="s013620384af7c8b4">
<source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be edited</source> <source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be edited</source>
<target>设备类型 <x id="0" equiv-text="${device.verboseName}"/> 无法被编辑</target>
</trans-unit> </trans-unit>
<trans-unit id="s4347135696fc7cde"> <trans-unit id="s4347135696fc7cde">
<source>Advanced flow settings</source> <source>Advanced flow settings</source>
<target>高级流程设置</target>
</trans-unit> </trans-unit>
<trans-unit id="sf52ff57fd136cc2f"> <trans-unit id="sf52ff57fd136cc2f">
<source>Enable this option to write password changes made in authentik back to Kerberos. Ignored if sync is disabled.</source> <source>Enable this option to write password changes made in authentik back to Kerberos. Ignored if sync is disabled.</source>
<target>启用此选项会将 authentik 作出的密码修改写入回 Kerberos。如果未启用同步则忽略。</target>
</trans-unit> </trans-unit>
<trans-unit id="s14a16542f956e11d"> <trans-unit id="s14a16542f956e11d">
<source>Realm settings</source> <source>Realm settings</source>
<target>领域设置</target>
</trans-unit> </trans-unit>
<trans-unit id="s9c2eae548d3c1c30"> <trans-unit id="s9c2eae548d3c1c30">
<source>Realm</source> <source>Realm</source>
<target>领域</target>
</trans-unit> </trans-unit>
<trans-unit id="s6b032212997e2491"> <trans-unit id="s6b032212997e2491">
<source>Kerberos 5 configuration</source> <source>Kerberos 5 configuration</source>
<target>Kerberos 5 配置</target>
</trans-unit> </trans-unit>
<trans-unit id="sbf50181022f47de3"> <trans-unit id="sbf50181022f47de3">
<source>Kerberos 5 configuration. See man krb5.conf(5) for configuration format. If left empty, a default krb5.conf will be used.</source> <source>Kerberos 5 configuration. See man krb5.conf(5) for configuration format. If left empty, a default krb5.conf will be used.</source>
<target>Kerberos 5 配置。请阅读 man krb5.conf(5) 了解配置格式。如果留空,则使用默认的 krb5.conf。</target>
</trans-unit> </trans-unit>
<trans-unit id="s2386539a0bd62fab"> <trans-unit id="s2386539a0bd62fab">
<source>Sync connection settings</source> <source>Sync connection settings</source>
<target>同步连接设置</target>
</trans-unit> </trans-unit>
<trans-unit id="s0d1a6f3fe81351f8"> <trans-unit id="s0d1a6f3fe81351f8">
<source>Sync principal</source> <source>Sync principal</source>
<target>同步主体</target>
</trans-unit> </trans-unit>
<trans-unit id="sa691d6e1974295fa"> <trans-unit id="sa691d6e1974295fa">
<source>Principal used to authenticate to the KDC for syncing.</source> <source>Principal used to authenticate to the KDC for syncing.</source>
<target>向 KDC 进行身份验证以进行同步的主体。</target>
</trans-unit> </trans-unit>
<trans-unit id="s977b9c629eed3d33"> <trans-unit id="s977b9c629eed3d33">
<source>Sync password</source> <source>Sync password</source>
<target>同步密码</target>
</trans-unit> </trans-unit>
<trans-unit id="s77772860385de948"> <trans-unit id="s77772860385de948">
<source>Password used to authenticate to the KDC for syncing. Optional if Sync keytab or Sync credentials cache is provided.</source> <source>Password used to authenticate to the KDC for syncing. Optional if Sync keytab or Sync credentials cache is provided.</source>
<target>向 KDC 进行身份验证以进行同步的密码。如果提供了同步 Keytab 或同步凭据缓存,则此选项是可选的。</target>
</trans-unit> </trans-unit>
<trans-unit id="sc59ec59c3d5e74dc"> <trans-unit id="sc59ec59c3d5e74dc">
<source>Sync keytab</source> <source>Sync keytab</source>
<target>同步 Keytab</target>
</trans-unit> </trans-unit>
<trans-unit id="scd42997958453f05"> <trans-unit id="scd42997958453f05">
<source>Keytab used to authenticate to the KDC for syncing. Optional if Sync password or Sync credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source> <source>Keytab used to authenticate to the KDC for syncing. Optional if Sync password or Sync credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source>
<target>向 KDC 进行身份验证以进行同步的 Keytab。如果提供了同步密码或同步凭据缓存则此选项是可选的。必须以 Base64 编码,或者形式为 TYPE:residual。</target>
</trans-unit> </trans-unit>
<trans-unit id="s60eaf439ccdca1f2"> <trans-unit id="s60eaf439ccdca1f2">
<source>Sync credentials cache</source> <source>Sync credentials cache</source>
<target>同步凭据缓存</target>
</trans-unit> </trans-unit>
<trans-unit id="s95722900b0c9026f"> <trans-unit id="s95722900b0c9026f">
<source>Credentials cache used to authenticate to the KDC for syncing. Optional if Sync password or Sync keytab is provided. Must be in the form TYPE:residual.</source> <source>Credentials cache used to authenticate to the KDC for syncing. Optional if Sync password or Sync keytab is provided. Must be in the form TYPE:residual.</source>
<target>向 KDC 进行身份验证以进行同步的凭据缓存。如果提供了同步密码或同步 Keytab则此选项是可选的。形式必须为 TYPE:residual。</target>
</trans-unit> </trans-unit>
<trans-unit id="sf9c055db98d7994a"> <trans-unit id="sf9c055db98d7994a">
<source>SPNEGO settings</source> <source>SPNEGO settings</source>
<target>SPNEGO 设置</target>
</trans-unit> </trans-unit>
<trans-unit id="sab580a45dc46937f"> <trans-unit id="sab580a45dc46937f">
<source>SPNEGO server name</source> <source>SPNEGO server name</source>
<target>SPNEGO 服务器名称</target>
</trans-unit> </trans-unit>
<trans-unit id="s7a79d6174d17ab2d"> <trans-unit id="s7a79d6174d17ab2d">
<source>Force the use of a specific server name for SPNEGO. Must be in the form HTTP@domain</source> <source>Force the use of a specific server name for SPNEGO. Must be in the form HTTP@domain</source>
<target>强制为 SPNEGO 使用特定服务器名称。形式必须为 HTTP@域名</target>
</trans-unit> </trans-unit>
<trans-unit id="sa4ba2b2081472ccd"> <trans-unit id="sa4ba2b2081472ccd">
<source>SPNEGO keytab</source> <source>SPNEGO keytab</source>
<target>SPNEGO Keytab</target>
</trans-unit> </trans-unit>
<trans-unit id="s64adda975c1106c0"> <trans-unit id="s64adda975c1106c0">
<source>Keytab used for SPNEGO. Optional if SPNEGO credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source> <source>Keytab used for SPNEGO. Optional if SPNEGO credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source>
<target>SPNEGO 使用的 Keytab。如果提供了 SPNEGO 凭据缓存,则此选项是可选的。必须以 Base64 编码,或者形式为 TYPE:residual。</target>
</trans-unit> </trans-unit>
<trans-unit id="s92247825b92587b5"> <trans-unit id="s92247825b92587b5">
<source>SPNEGO credentials cache</source> <source>SPNEGO credentials cache</source>
<target>SPNEGO 凭据缓存</target>
</trans-unit> </trans-unit>
<trans-unit id="sd9757c345e4062f8"> <trans-unit id="sd9757c345e4062f8">
<source>Credentials cache used for SPNEGO. Optional if SPNEGO keytab is provided. Must be in the form TYPE:residual.</source> <source>Credentials cache used for SPNEGO. Optional if SPNEGO keytab is provided. Must be in the form TYPE:residual.</source>
<target>SPNEGO 使用的凭据缓存。如果提供了 SPNEGO Keytab则此选项是可选的。形式必须为 TYPE:residual。</target>
</trans-unit> </trans-unit>
<trans-unit id="s734ab8fbcae0b69e"> <trans-unit id="s734ab8fbcae0b69e">
<source>Kerberos Attribute mapping</source> <source>Kerberos Attribute mapping</source>
<target>Kerberos 属性映射</target>
</trans-unit> </trans-unit>
<trans-unit id="s2c378e86e025fdb2"> <trans-unit id="s2c378e86e025fdb2">
<source>Update Kerberos Source</source> <source>Update Kerberos Source</source>
<target>更新 Kerberos 源</target>
</trans-unit> </trans-unit>
<trans-unit id="s03e4044abe0b556c"> <trans-unit id="s03e4044abe0b556c">
<source>User database + Kerberos password</source> <source>User database + Kerberos password</source>
<target>用户数据库 + Kerberos 密码</target>
</trans-unit> </trans-unit>
<trans-unit id="s98bb2ae796f1ceef"> <trans-unit id="s98bb2ae796f1ceef">
<source>Select another authentication method</source> <source>Select another authentication method</source>
<target>选择另一种身份验证方法</target>
</trans-unit> </trans-unit>
<trans-unit id="s21d95b4651ad7a1e"> <trans-unit id="s21d95b4651ad7a1e">
<source>Enter a one-time recovery code for this user.</source> <source>Enter a one-time recovery code for this user.</source>
<target>为此用户输入一次性恢复代码。</target>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
<target>请输入来自您身份验证设备的代码。</target>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
<target>Kerberos 源目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
<target>验证码阶段</target>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
<target>设置后,添加与验证码阶段完全相同的功能,但融入识别阶段。</target>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
<target>端点 Google Chrome 设备信任处于预览状态。</target>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -5777,6 +5777,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="sfc31264ef7ff86ef"> <trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
</trans-unit> </trans-unit>
@ -5921,6 +5924,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -6972,18 +6978,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -6618,6 +6618,11 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Please enter your code</source> <source>Please enter your code</source>
<target>请输入您的代码</target> <target>请输入您的代码</target>
</trans-unit>
<trans-unit id="s18b910437b73e8e8">
<source>Return to device picker</source>
<target>返回设备选择器</target>
</trans-unit> </trans-unit>
<trans-unit id="se409d01b52c4e12f"> <trans-unit id="se409d01b52c4e12f">
<source>Retry authentication</source> <source>Retry authentication</source>
@ -7648,6 +7653,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>适用于按根域名配置的 nginx 的 auth_request 或 traefik 的 forwardAuth</target> <target>适用于按根域名配置的 nginx 的 auth_request 或 traefik 的 forwardAuth</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC 目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>新创建用户使用的用户类型。</target> <target>新创建用户使用的用户类型。</target>
@ -7840,6 +7849,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Create Endpoint</source> <source>Create Endpoint</source>
<target>创建端点</target> <target>创建端点</target>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
<target>RAC 目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
<target>更新 RAC 提供程序</target> <target>更新 RAC 提供程序</target>
@ -9117,150 +9130,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s8a598f7aef81c3bc"> <trans-unit id="s8a598f7aef81c3bc">
<source>Key used to encrypt the tokens.</source> <source>Key used to encrypt the tokens.</source>
<target>用于加密令牌的密钥。</target> <target>用于加密令牌的密钥。</target>
</trans-unit>
<trans-unit id="sbfee780fa0a2c83e">
<source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be deleted</source>
<target>设备类型 <x id="0" equiv-text="${device.verboseName}"/> 无法被删除</target>
</trans-unit>
<trans-unit id="s336936629cdeb3e5">
<source>Stage used to verify users' browsers using Google Chrome Device Trust. This stage can be used in authentication/authorization flows.</source>
<target>通过 Google Chrome 设备信任来验证用户浏览器的阶段。此阶段可在身份验证/授权流程中使用。</target>
</trans-unit>
<trans-unit id="s85fe794c71b4ace8">
<source>Google Verified Access API</source>
<target>Google Verified Access API</target>
</trans-unit>
<trans-unit id="s013620384af7c8b4">
<source>Device type <x id="0" equiv-text="${device.verboseName}"/> cannot be edited</source>
<target>设备类型 <x id="0" equiv-text="${device.verboseName}"/> 无法被编辑</target>
</trans-unit>
<trans-unit id="s4347135696fc7cde">
<source>Advanced flow settings</source>
<target>高级流程设置</target>
</trans-unit>
<trans-unit id="sf52ff57fd136cc2f">
<source>Enable this option to write password changes made in authentik back to Kerberos. Ignored if sync is disabled.</source>
<target>启用此选项会将 authentik 作出的密码修改写入回 Kerberos。如果未启用同步则忽略。</target>
</trans-unit>
<trans-unit id="s14a16542f956e11d">
<source>Realm settings</source>
<target>领域设置</target>
</trans-unit>
<trans-unit id="s9c2eae548d3c1c30">
<source>Realm</source>
<target>领域</target>
</trans-unit>
<trans-unit id="s6b032212997e2491">
<source>Kerberos 5 configuration</source>
<target>Kerberos 5 配置</target>
</trans-unit>
<trans-unit id="sbf50181022f47de3">
<source>Kerberos 5 configuration. See man krb5.conf(5) for configuration format. If left empty, a default krb5.conf will be used.</source>
<target>Kerberos 5 配置。请阅读 man krb5.conf(5) 了解配置格式。如果留空,则使用默认的 krb5.conf。</target>
</trans-unit>
<trans-unit id="s2386539a0bd62fab">
<source>Sync connection settings</source>
<target>同步连接设置</target>
</trans-unit>
<trans-unit id="s0d1a6f3fe81351f8">
<source>Sync principal</source>
<target>同步主体</target>
</trans-unit>
<trans-unit id="sa691d6e1974295fa">
<source>Principal used to authenticate to the KDC for syncing.</source>
<target>向 KDC 进行身份验证以进行同步的主体。</target>
</trans-unit>
<trans-unit id="s977b9c629eed3d33">
<source>Sync password</source>
<target>同步密码</target>
</trans-unit>
<trans-unit id="s77772860385de948">
<source>Password used to authenticate to the KDC for syncing. Optional if Sync keytab or Sync credentials cache is provided.</source>
<target>向 KDC 进行身份验证以进行同步的密码。如果提供了同步 Keytab 或同步凭据缓存,则此选项是可选的。</target>
</trans-unit>
<trans-unit id="sc59ec59c3d5e74dc">
<source>Sync keytab</source>
<target>同步 Keytab</target>
</trans-unit>
<trans-unit id="scd42997958453f05">
<source>Keytab used to authenticate to the KDC for syncing. Optional if Sync password or Sync credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source>
<target>向 KDC 进行身份验证以进行同步的 Keytab。如果提供了同步密码或同步凭据缓存则此选项是可选的。必须以 Base64 编码,或者形式为 TYPE:residual。</target>
</trans-unit>
<trans-unit id="s60eaf439ccdca1f2">
<source>Sync credentials cache</source>
<target>同步凭据缓存</target>
</trans-unit>
<trans-unit id="s95722900b0c9026f">
<source>Credentials cache used to authenticate to the KDC for syncing. Optional if Sync password or Sync keytab is provided. Must be in the form TYPE:residual.</source>
<target>向 KDC 进行身份验证以进行同步的凭据缓存。如果提供了同步密码或同步 Keytab则此选项是可选的。形式必须为 TYPE:residual。</target>
</trans-unit>
<trans-unit id="sf9c055db98d7994a">
<source>SPNEGO settings</source>
<target>SPNEGO 设置</target>
</trans-unit>
<trans-unit id="sab580a45dc46937f">
<source>SPNEGO server name</source>
<target>SPNEGO 服务器名称</target>
</trans-unit>
<trans-unit id="s7a79d6174d17ab2d">
<source>Force the use of a specific server name for SPNEGO. Must be in the form HTTP@domain</source>
<target>强制为 SPNEGO 使用特定服务器名称。形式必须为 HTTP@域名</target>
</trans-unit>
<trans-unit id="sa4ba2b2081472ccd">
<source>SPNEGO keytab</source>
<target>SPNEGO Keytab</target>
</trans-unit>
<trans-unit id="s64adda975c1106c0">
<source>Keytab used for SPNEGO. Optional if SPNEGO credentials cache is provided. Must be base64 encoded or in the form TYPE:residual.</source>
<target>SPNEGO 使用的 Keytab。如果提供了 SPNEGO 凭据缓存,则此选项是可选的。必须以 Base64 编码,或者形式为 TYPE:residual。</target>
</trans-unit>
<trans-unit id="s92247825b92587b5">
<source>SPNEGO credentials cache</source>
<target>SPNEGO 凭据缓存</target>
</trans-unit>
<trans-unit id="sd9757c345e4062f8">
<source>Credentials cache used for SPNEGO. Optional if SPNEGO keytab is provided. Must be in the form TYPE:residual.</source>
<target>SPNEGO 使用的凭据缓存。如果提供了 SPNEGO Keytab则此选项是可选的。形式必须为 TYPE:residual。</target>
</trans-unit>
<trans-unit id="s734ab8fbcae0b69e">
<source>Kerberos Attribute mapping</source>
<target>Kerberos 属性映射</target>
</trans-unit>
<trans-unit id="s2c378e86e025fdb2">
<source>Update Kerberos Source</source>
<target>更新 Kerberos 源</target>
</trans-unit>
<trans-unit id="s03e4044abe0b556c">
<source>User database + Kerberos password</source>
<target>用户数据库 + Kerberos 密码</target>
</trans-unit>
<trans-unit id="s98bb2ae796f1ceef">
<source>Select another authentication method</source>
<target>选择另一种身份验证方法</target>
</trans-unit>
<trans-unit id="s21d95b4651ad7a1e">
<source>Enter a one-time recovery code for this user.</source>
<target>为此用户输入一次性恢复代码。</target>
</trans-unit>
<trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source>
<target>请输入来自您身份验证设备的代码。</target>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
<target>Kerberos 源目前处于预览状态。</target>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
<target>验证码阶段</target>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
<target>设置后,添加与验证码阶段完全相同的功能,但融入识别阶段。</target>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
<target>端点 Google Chrome 设备信任处于预览状态。</target>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -7590,6 +7590,10 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source> <source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
<target>適用於每個主網域的 nginx 的「auth_request」或 traefik 的「forwardAuth」</target> <target>適用於每個主網域的 nginx 的「auth_request」或 traefik 的「forwardAuth」</target>
</trans-unit> </trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
<target>RBAC 正處於預覽版本。</target>
</trans-unit>
<trans-unit id="s32babfed740fd3c1"> <trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source> <source>User type used for newly created users.</source>
<target>用於建立使用者的使用者類型。</target> <target>用於建立使用者的使用者類型。</target>
@ -7756,6 +7760,9 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s38e7cd1a24e70faa"> <trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source> <source>Create Endpoint</source>
</trans-unit> </trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f"> <trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source> <source>Update RAC Provider</source>
</trans-unit> </trans-unit>
@ -8807,18 +8814,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit> </trans-unit>
<trans-unit id="s2e1d5a7d320c25ef"> <trans-unit id="s2e1d5a7d320c25ef">
<source>Enter the code from your authenticator device.</source> <source>Enter the code from your authenticator device.</source>
</trans-unit>
<trans-unit id="scc1a17d28912e974">
<source>Kerberos Source is in preview.</source>
</trans-unit>
<trans-unit id="s54154a8d64a3597b">
<source>Captcha stage</source>
</trans-unit>
<trans-unit id="s0c250af62ddbf801">
<source>When set, adds functionality exactly like a Captcha stage, but baked into the Identification stage.</source>
</trans-unit>
<trans-unit id="sabf8a430d504f8c8">
<source>Endpoint Google Chrome Device Trust is in preview.</source>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>

View File

@ -1,6 +1,5 @@
--- ---
title: Applications title: Applications
slug: /applications
--- ---
Applications, as defined in authentik, are used to configure and separate the authorization/access control and the appearance of a specific software application in the **My applications** page. Applications, as defined in authentik, are used to configure and separate the authorization/access control and the appearance of a specific software application in the **My applications** page.

View File

@ -2,15 +2,17 @@
title: Captcha stage title: Captcha stage
--- ---
This stage adds a form of verification using [Google's ReCaptcha](https://www.google.com/recaptcha/intro/v3.html) or compatible services. Currently supported implementations: This stage adds a form of verification using [Google's reCAPTCHA](https://www.google.com/recaptcha/intro/v3.html) or compatible services.
- ReCaptcha Currently supported implementations:
- hCaptcha
- Turnstile - [Google reCAPTCHA](#google-recaptcha)
- [hCaptcha](#hcaptcha)
- [Cloudflare Turnstile](#cloudflare-turnstile)
## Captcha provider configuration ## Captcha provider configuration
### Google ReCaptcha ### Google reCAPTCHA
This stage has two required fields: Public key and private key. These can both be acquired at https://www.google.com/recaptcha/admin. This stage has two required fields: Public key and private key. These can both be acquired at https://www.google.com/recaptcha/admin.
@ -18,10 +20,11 @@ This stage has two required fields: Public key and private key. These can both b
#### Configuration options #### Configuration options
- JS URL: `https://www.recaptcha.net/recaptcha/api.js` - Interactive: Enabled when using reCAPTCHA v3
- API URL: `https://www.recaptcha.net/recaptcha/api/siteverify`
- Score minimum threshold: `0.5` - Score minimum threshold: `0.5`
- Score maximum threshold: `1` - Score maximum threshold: `1`
- JS URL: `https://www.recaptcha.net/recaptcha/api.js`
- API URL: `https://www.recaptcha.net/recaptcha/api/siteverify`
### hCaptcha ### hCaptcha
@ -29,6 +32,7 @@ See https://docs.hcaptcha.com/switch
#### Configuration options #### Configuration options
- Interactive: Enabled
- JS URL: `https://js.hcaptcha.com/1/api.js` - JS URL: `https://js.hcaptcha.com/1/api.js`
- API URL: `https://api.hcaptcha.com/siteverify` - API URL: `https://api.hcaptcha.com/siteverify`
@ -37,16 +41,13 @@ See https://docs.hcaptcha.com/switch
- Score minimum threshold: `0` - Score minimum threshold: `0`
- Score maximum threshold: `0.5` - Score maximum threshold: `0.5`
### Turnstile ### Cloudflare Turnstile
See https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha See https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha
:::warning
To use Cloudflare Turnstile, the site must be configured to use the "Invisible" mode, otherwise the widget will be rendered incorrectly.
:::
#### Configuration options #### Configuration options
- Interactive: Enabled if the Turnstile instance is configured as visible or managed
- JS URL: `https://challenges.cloudflare.com/turnstile/v0/api.js` - JS URL: `https://challenges.cloudflare.com/turnstile/v0/api.js`
- API URL: `https://challenges.cloudflare.com/turnstile/v0/siteverify` - API URL: `https://challenges.cloudflare.com/turnstile/v0/siteverify`

View File

@ -32,6 +32,10 @@ This policy can enforce regular password rotation by expiring set passwords afte
### Password Policy ### Password Policy
:::warning
By default, authentik's Password policy is compliant with [NIST's recommendations](https://pages.nist.gov/800-63-4/sp800-63b.html#password) for passwords. To remain compliant with NIST, be cautious when editing the default values. For additional hardening configuration settings, refer to [Hardening authentik](../../security/security-hardening.md#password-policy).
:::
This policy allows you to specify password rules, such as length and required characters. This policy allows you to specify password rules, such as length and required characters.
The following rules can be set: The following rules can be set:

File diff suppressed because it is too large Load Diff

View File

@ -286,20 +286,6 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2024.8
- web: Fix missing integrity fields in package-lock.json (#11509) - web: Fix missing integrity fields in package-lock.json (#11509)
- web/admin: fix Authentication flow being required (cherry-pick #11496) (#11497) - web/admin: fix Authentication flow being required (cherry-pick #11496) (#11497)
## Fixed in 2024.8.4
- blueprints: fix validation error when using internal storage (cherry-pick #11654) (#11656)
- core: fix permission check for scoped impersonation (cherry-pick #11603) (#11650)
- internal: restore /ping behaviour for embedded outpost (cherry-pick #11568) (#11570)
- policies/event_matcher: fix inconsistent behaviour (cherry-pick #11724) (#11726)
- providers/oauth2: don't overwrite attributes when updating service account (cherry-pick #11709) (#11723)
- providers/saml: fix incorrect ds:Reference URI (cherry-pick #11699) (#11701)
- providers/scim: add comparison with existing group on update and delta update users (cherry-pick #11414) (#11796)
- providers/scim: clamp batch size for patch requests (cherry-pick #11797) (#11802)
- providers/scim: handle no members in group in consistency check (cherry-pick #11801) (#11812)
- web/admin: fix invalid create date shown for MFA registered before date was saved (cherry-pick #11728) (#11729)
- web/admin: fix sync single button throwing error (cherry-pick #11727) (#11730)
## API Changes ## API Changes
#### What's New #### What's New

View File

@ -4,6 +4,17 @@ title: Hardening authentik
While authentik is secure out of the box, you can take steps to further increase the security of an authentik instance. As everyone knows, there is a consequential tradeoff between security and convenience. All of these hardening practices have an impact on the user experience and should only be applied knowing this tradeoff. While authentik is secure out of the box, you can take steps to further increase the security of an authentik instance. As everyone knows, there is a consequential tradeoff between security and convenience. All of these hardening practices have an impact on the user experience and should only be applied knowing this tradeoff.
### Password policy
authentik's default Password policy complies with the [NIST SP 800-63 Digital Identity Guidelines](https://pages.nist.gov/800-63-4/sp800-63b.html#password).
However, for further hardening compliant to the NIST Guidelines, consider
- setting the length of the password to a minimum of 15 characters, and
- enabling the "Check haveibeenpwned.com" blocklist comparison (note that this cannot be used on Air-gapped instances)
For further options, see [Password policy](../customize/policies/index.md#password-policy).
### Expressions ### Expressions
[Expressions](../customize/policies/expression.mdx) allow super-users and other highly privileged users to create custom logic within authentik to modify its behaviour. Editing/creating these expressions is, by default, limited to super-users and any related events are fully logged. [Expressions](../customize/policies/expression.mdx) allow super-users and other highly privileged users to create custom logic within authentik to modify its behaviour. Editing/creating these expressions is, by default, limited to super-users and any related events are fully logged.

View File

@ -8895,9 +8895,9 @@
"integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ=="
}, },
"node_modules/elliptic": { "node_modules/elliptic": {
"version": "6.6.0", "version": "6.5.7",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
"integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
"dependencies": { "dependencies": {
"bn.js": "^4.11.9", "bn.js": "^4.11.9",
"brorand": "^1.1.0", "brorand": "^1.1.0",