Merge branch 'main' into dev

* main:
  web: bump API Client version (#9967)
  stages/captcha: rework (#9959)
  website/docs: fixed broken links to helm repo (#9960)
  core: bump pydantic from 2.7.2 to 2.7.3 (#9962)
  web: bump the wdio group in /tests/wdio with 4 updates (#9963)
This commit is contained in:
Ken Sternberg
2024-06-04 14:57:57 -07:00
16 changed files with 459 additions and 182 deletions

View File

@ -12,7 +12,15 @@ class CaptchaStageSerializer(StageSerializer):
class Meta: class Meta:
model = CaptchaStage model = CaptchaStage
fields = StageSerializer.Meta.fields + ["public_key", "private_key", "js_url", "api_url"] fields = StageSerializer.Meta.fields + [
"public_key",
"private_key",
"js_url",
"api_url",
"score_min_threshold",
"score_max_threshold",
"error_on_invalid_score",
]
extra_kwargs = {"private_key": {"write_only": True}} extra_kwargs = {"private_key": {"write_only": True}}

View File

@ -0,0 +1,31 @@
# Generated by Django 5.0.6 on 2024-06-03 15:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_captcha", "0002_captchastage_api_url_captchastage_js_url_and_more"),
]
operations = [
migrations.AddField(
model_name="captchastage",
name="error_on_invalid_score",
field=models.BooleanField(
default=True,
help_text="When enabled and the received captcha score is outside of the given threshold, the stage will show an error message. When not enabled, the flow will continue, but the data from the captcha will be available in the context for policy decisions",
),
),
migrations.AddField(
model_name="captchastage",
name="score_max_threshold",
field=models.FloatField(default=1.0),
),
migrations.AddField(
model_name="captchastage",
name="score_min_threshold",
field=models.FloatField(default=0.5),
),
]

View File

@ -14,6 +14,18 @@ class CaptchaStage(Stage):
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."))
score_min_threshold = models.FloatField(default=0.5) # Default values for reCaptcha
score_max_threshold = models.FloatField(default=1.0) # Default values for reCaptcha
error_on_invalid_score = models.BooleanField(
default=True,
help_text=_(
"When enabled and the received captcha score is outside of the given threshold, "
"the stage will show an error message. When not enabled, the flow will continue, "
"but the data from the captcha will be available in the context for policy decisions"
),
)
js_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api.js") js_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api.js")
api_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api/siteverify") api_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api/siteverify")

View File

@ -1,6 +1,7 @@
"""authentik captcha stage""" """authentik captcha stage"""
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.utils.translation import gettext_lazy as _
from requests import RequestException from requests import RequestException
from rest_framework.fields import CharField from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
@ -16,6 +17,8 @@ from authentik.lib.utils.http import get_http_session
from authentik.root.middleware import ClientIPMiddleware from authentik.root.middleware import ClientIPMiddleware
from authentik.stages.captcha.models import CaptchaStage from authentik.stages.captcha.models import CaptchaStage
PLAN_CONTEXT_CAPTCHA = "captcha"
class CaptchaChallenge(WithUserInfoChallenge): class CaptchaChallenge(WithUserInfoChallenge):
"""Site public key""" """Site public key"""
@ -48,11 +51,24 @@ class CaptchaChallengeResponse(ChallengeResponse):
) )
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
if not data.get("success", False): if stage.error_on_invalid_score:
raise ValidationError(f"Failed to validate token: {data.get('error-codes', '')}") if not data.get("success", False):
except RequestException as exc: raise ValidationError(
raise ValidationError("Failed to validate token") from exc _(
return token "Failed to validate token: {error}".format(
error=data.get("error-codes", _("Unknown error"))
)
)
)
if "score" in data:
score = float(data.get("score"))
if stage.score_max_threshold > -1 and score > stage.score_max_threshold:
raise ValidationError(_("Invalid captcha response"))
if stage.score_min_threshold > -1 and score < stage.score_min_threshold:
raise ValidationError(_("Invalid captcha response"))
except (RequestException, TypeError) as exc:
raise ValidationError(_("Failed to validate token")) from exc
return data
class CaptchaStageView(ChallengeStageView): class CaptchaStageView(ChallengeStageView):
@ -69,5 +85,10 @@ class CaptchaStageView(ChallengeStageView):
} }
) )
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse: def challenge_valid(self, response: CaptchaChallengeResponse) -> HttpResponse:
response = response.validated_data["token"]
self.executor.plan.context[PLAN_CONTEXT_CAPTCHA] = {
"response": response,
"stage": self.executor.current_stage,
}
return self.executor.stage_ok() return self.executor.stage_ok()

View File

@ -1,6 +1,7 @@
"""captcha tests""" """captcha tests"""
from django.urls import reverse from django.urls import reverse
from requests_mock import Mocker
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_flow
from authentik.flows.markers import StageMarker from authentik.flows.markers import StageMarker
@ -30,8 +31,89 @@ class TestCaptchaStage(FlowTestCase):
) )
self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2) self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)
def test_valid(self): @Mocker()
def test_valid(self, mock: Mocker):
"""Test valid captcha""" """Test valid captcha"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": 0.5,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
@Mocker()
def test_invalid_score_high(self, mock: Mocker):
"""Test invalid captcha (score too high)"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": 99,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
component="ak-stage-captcha",
response_errors={"token": [{"string": "Invalid captcha response", "code": "invalid"}]},
)
@Mocker()
def test_invalid_score_low(self, mock: Mocker):
"""Test invalid captcha (score too low)"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": -3,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
component="ak-stage-captcha",
response_errors={"token": [{"string": "Invalid captcha response", "code": "invalid"}]},
)
@Mocker()
def test_invalid_score_low_continue(self, mock: Mocker):
"""Test invalid captcha (score too low, but continue)"""
self.stage.error_on_invalid_score = False
self.stage.save()
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": -3,
},
)
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
session[SESSION_KEY_PLAN] = plan session[SESSION_KEY_PLAN] = plan

View File

@ -6164,6 +6164,19 @@
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
"title": "Api url" "title": "Api url"
},
"score_min_threshold": {
"type": "number",
"title": "Score min threshold"
},
"score_max_threshold": {
"type": "number",
"title": "Score max threshold"
},
"error_on_invalid_score": {
"type": "boolean",
"title": "Error on invalid score",
"description": "When enabled and the received captcha score is outside of the given threshold, the stage will show an error message. When not enabled, the flow will continue, but the data from the captcha will be available in the context for policy decisions"
} }
}, },
"required": [] "required": []

170
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]] [[package]]
name = "aiohttp" name = "aiohttp"
@ -3376,19 +3376,19 @@ files = [
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "2.7.2" version = "2.7.3"
description = "Data validation using Python type hints" description = "Data validation using Python type hints"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "pydantic-2.7.2-py3-none-any.whl", hash = "sha256:834ab954175f94e6e68258537dc49402c4a5e9d0409b9f1b86b7e934a8372de7"}, {file = "pydantic-2.7.3-py3-none-any.whl", hash = "sha256:ea91b002777bf643bb20dd717c028ec43216b24a6001a280f83877fd2655d0b4"},
{file = "pydantic-2.7.2.tar.gz", hash = "sha256:71b2945998f9c9b7919a45bde9a50397b289937d215ae141c1d0903ba7149fd7"}, {file = "pydantic-2.7.3.tar.gz", hash = "sha256:c46c76a40bb1296728d7a8b99aa73dd70a48c3510111ff290034f860c99c419e"},
] ]
[package.dependencies] [package.dependencies]
annotated-types = ">=0.4.0" annotated-types = ">=0.4.0"
email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""} email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
pydantic-core = "2.18.3" pydantic-core = "2.18.4"
typing-extensions = ">=4.6.1" typing-extensions = ">=4.6.1"
[package.extras] [package.extras]
@ -3396,90 +3396,90 @@ email = ["email-validator (>=2.0.0)"]
[[package]] [[package]]
name = "pydantic-core" name = "pydantic-core"
version = "2.18.3" version = "2.18.4"
description = "Core functionality for Pydantic validation and serialization" description = "Core functionality for Pydantic validation and serialization"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "pydantic_core-2.18.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:744697428fcdec6be5670460b578161d1ffe34743a5c15656be7ea82b008197c"}, {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"},
{file = "pydantic_core-2.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b40c05ced1ba4218b14986fe6f283d22e1ae2ff4c8e28881a70fb81fbfcda7"}, {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a9a75622357076efb6b311983ff190fbfb3c12fc3a853122b34d3d358126c"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2e253af04ceaebde8eb201eb3f3e3e7e390f2d275a88300d6a1959d710539e2"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:855ec66589c68aa367d989da5c4755bb74ee92ccad4fdb6af942c3612c067e34"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3e42bb54e7e9d72c13ce112e02eb1b3b55681ee948d748842171201a03a98a"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6ac9ffccc9d2e69d9fba841441d4259cb668ac180e51b30d3632cd7abca2b9b"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c56eca1686539fa0c9bda992e7bd6a37583f20083c37590413381acfc5f192d6"}, {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"},
{file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17954d784bf8abfc0ec2a633108207ebc4fa2df1a0e4c0c3ccbaa9bb01d2c426"}, {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"},
{file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:98ed737567d8f2ecd54f7c8d4f8572ca7c7921ede93a2e52939416170d357812"}, {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"},
{file = "pydantic_core-2.18.3-cp310-none-win32.whl", hash = "sha256:9f9e04afebd3ed8c15d67a564ed0a34b54e52136c6d40d14c5547b238390e779"}, {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"},
{file = "pydantic_core-2.18.3-cp310-none-win_amd64.whl", hash = "sha256:45e4ffbae34f7ae30d0047697e724e534a7ec0a82ef9994b7913a412c21462a0"}, {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"},
{file = "pydantic_core-2.18.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9ebe8231726c49518b16b237b9fe0d7d361dd221302af511a83d4ada01183ab"}, {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"},
{file = "pydantic_core-2.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8e20e15d18bf7dbb453be78a2d858f946f5cdf06c5072453dace00ab652e2b2"}, {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d9ff283cd3459fa0bf9b0256a2b6f01ac1ff9ffb034e24457b9035f75587cb"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f7ef5f0ebb77ba24c9970da18b771711edc5feaf00c10b18461e0f5f5949231"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73038d66614d2e5cde30435b5afdced2b473b4c77d4ca3a8624dd3e41a9c19be"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6afd5c867a74c4d314c557b5ea9520183fadfbd1df4c2d6e09fd0d990ce412cd"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd7df92f28d351bb9f12470f4c533cf03d1b52ec5a6e5c58c65b183055a60106"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80aea0ffeb1049336043d07799eace1c9602519fb3192916ff525b0287b2b1e4"}, {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"},
{file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaee40f25bba38132e655ffa3d1998a6d576ba7cf81deff8bfa189fb43fd2bbe"}, {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"},
{file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9128089da8f4fe73f7a91973895ebf2502539d627891a14034e45fb9e707e26d"}, {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"},
{file = "pydantic_core-2.18.3-cp311-none-win32.whl", hash = "sha256:fec02527e1e03257aa25b1a4dcbe697b40a22f1229f5d026503e8b7ff6d2eda7"}, {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"},
{file = "pydantic_core-2.18.3-cp311-none-win_amd64.whl", hash = "sha256:58ff8631dbab6c7c982e6425da8347108449321f61fe427c52ddfadd66642af7"}, {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"},
{file = "pydantic_core-2.18.3-cp311-none-win_arm64.whl", hash = "sha256:3fc1c7f67f34c6c2ef9c213e0f2a351797cda98249d9ca56a70ce4ebcaba45f4"}, {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"},
{file = "pydantic_core-2.18.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0928cde2ae416a2d1ebe6dee324709c6f73e93494d8c7aea92df99aab1fc40f"}, {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"},
{file = "pydantic_core-2.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bee9bb305a562f8b9271855afb6ce00223f545de3d68560b3c1649c7c5295e9"}, {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e862823be114387257dacbfa7d78547165a85d7add33b446ca4f4fae92c7ff5c"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a36f78674cbddc165abab0df961b5f96b14461d05feec5e1f78da58808b97e7"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba905d184f62e7ddbb7a5a751d8a5c805463511c7b08d1aca4a3e8c11f2e5048"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fdd362f6a586e681ff86550b2379e532fee63c52def1c666887956748eaa326"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b214b7ee3bd3b865e963dbed0f8bc5375f49449d70e8d407b567af3222aae4"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691018785779766127f531674fa82bb368df5b36b461622b12e176c18e119022"}, {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"},
{file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60e4c625e6f7155d7d0dcac151edf5858102bc61bf959d04469ca6ee4e8381bd"}, {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"},
{file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4e651e47d981c1b701dcc74ab8fec5a60a5b004650416b4abbef13db23bc7be"}, {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"},
{file = "pydantic_core-2.18.3-cp312-none-win32.whl", hash = "sha256:ffecbb5edb7f5ffae13599aec33b735e9e4c7676ca1633c60f2c606beb17efc5"}, {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"},
{file = "pydantic_core-2.18.3-cp312-none-win_amd64.whl", hash = "sha256:2c8333f6e934733483c7eddffdb094c143b9463d2af7e6bd85ebcb2d4a1b82c6"}, {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"},
{file = "pydantic_core-2.18.3-cp312-none-win_arm64.whl", hash = "sha256:7a20dded653e516a4655f4c98e97ccafb13753987434fe7cf044aa25f5b7d417"}, {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"},
{file = "pydantic_core-2.18.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:eecf63195be644b0396f972c82598cd15693550f0ff236dcf7ab92e2eb6d3522"}, {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"},
{file = "pydantic_core-2.18.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c44efdd3b6125419c28821590d7ec891c9cb0dff33a7a78d9d5c8b6f66b9702"}, {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e59fca51ffbdd1638b3856779342ed69bcecb8484c1d4b8bdb237d0eb5a45e2"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70cf099197d6b98953468461d753563b28e73cf1eade2ffe069675d2657ed1d5"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63081a49dddc6124754b32a3774331467bfc3d2bd5ff8f10df36a95602560361"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:370059b7883485c9edb9655355ff46d912f4b03b009d929220d9294c7fd9fd60"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a64faeedfd8254f05f5cf6fc755023a7e1606af3959cfc1a9285744cc711044"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19d2e725de0f90d8671f89e420d36c3dd97639b98145e42fcc0e1f6d492a46dc"}, {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"},
{file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:67bc078025d70ec5aefe6200ef094576c9d86bd36982df1301c758a9fff7d7f4"}, {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"},
{file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:adf952c3f4100e203cbaf8e0c907c835d3e28f9041474e52b651761dc248a3c0"}, {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"},
{file = "pydantic_core-2.18.3-cp38-none-win32.whl", hash = "sha256:9a46795b1f3beb167eaee91736d5d17ac3a994bf2215a996aed825a45f897558"}, {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"},
{file = "pydantic_core-2.18.3-cp38-none-win_amd64.whl", hash = "sha256:200ad4e3133cb99ed82342a101a5abf3d924722e71cd581cc113fe828f727fbc"}, {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"},
{file = "pydantic_core-2.18.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:304378b7bf92206036c8ddd83a2ba7b7d1a5b425acafff637172a3aa72ad7083"}, {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"},
{file = "pydantic_core-2.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c826870b277143e701c9ccf34ebc33ddb4d072612683a044e7cce2d52f6c3fef"}, {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e201935d282707394f3668380e41ccf25b5794d1b131cdd96b07f615a33ca4b1"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5560dda746c44b48bf82b3d191d74fe8efc5686a9ef18e69bdabccbbb9ad9442"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b32c2a1f8032570842257e4c19288eba9a2bba4712af542327de9a1204faff8"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:929c24e9dea3990bc8bcd27c5f2d3916c0c86f5511d2caa69e0d5290115344a9"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a8376fef60790152564b0eab376b3e23dd6e54f29d84aad46f7b264ecca943"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dccf3ef1400390ddd1fb55bf0632209d39140552d068ee5ac45553b556780e06"}, {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"},
{file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41dbdcb0c7252b58fa931fec47937edb422c9cb22528f41cb8963665c372caf6"}, {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"},
{file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:666e45cf071669fde468886654742fa10b0e74cd0fa0430a46ba6056b24fb0af"}, {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"},
{file = "pydantic_core-2.18.3-cp39-none-win32.whl", hash = "sha256:f9c08cabff68704a1b4667d33f534d544b8a07b8e5d039c37067fceb18789e78"}, {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"},
{file = "pydantic_core-2.18.3-cp39-none-win_amd64.whl", hash = "sha256:4afa5f5973e8572b5c0dcb4e2d4fda7890e7cd63329bd5cc3263a25c92ef0026"}, {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:77319771a026f7c7d29c6ebc623de889e9563b7087911b46fd06c044a12aa5e9"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:df11fa992e9f576473038510d66dd305bcd51d7dd508c163a8c8fe148454e059"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d531076bdfb65af593326ffd567e6ab3da145020dafb9187a1d131064a55f97c"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33ce258e4e6e6038f2b9e8b8a631d17d017567db43483314993b3ca345dcbbb"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9cd7f5635b719939019be9bda47ecb56e165e51dd26c9a217a433e3d0d59a9"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cd4a032bb65cc132cae1fe3e52877daecc2097965cd3914e44fbd12b00dae7c5"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f2718430098bcdf60402136c845e4126a189959d103900ebabb6774a5d9fdb"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c0037a92cf0c580ed14e10953cdd26528e8796307bb8bb312dc65f71547df04d"}, {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b95a0972fac2b1ff3c94629fc9081b16371dad870959f1408cc33b2f78ad347a"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a62e437d687cc148381bdd5f51e3e81f5b20a735c55f690c5be94e05da2b0d5c"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b367a73a414bbb08507da102dc2cde0fa7afe57d09b3240ce82a16d608a7679c"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ecce4b2360aa3f008da3327d652e74a0e743908eac306198b47e1c58b03dd2b"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4435b8d83f0c9561a2a9585b1de78f1abb17cb0cef5f39bf6a4b47d19bafe3"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:616221a6d473c5b9aa83fa8982745441f6a4a62a66436be9445c65f241b86c94"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7e6382ce89a92bc1d0c0c5edd51e931432202b9080dc921d8d003e616402efd1"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff58f379345603d940e461eae474b6bbb6dab66ed9a851ecd3cb3709bf4dcf6a"}, {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"},
{file = "pydantic_core-2.18.3.tar.gz", hash = "sha256:432e999088d85c8f36b9a3f769a8e2b57aabd817bbb729a90d1fe7f18f6f1f39"}, {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"},
] ]
[package.dependencies] [package.dependencies]

View File

@ -34067,6 +34067,18 @@ components:
type: string type: string
api_url: api_url:
type: string type: string
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
required: required:
- component - component
- meta_model_name - meta_model_name
@ -34101,6 +34113,18 @@ components:
api_url: api_url:
type: string type: string
minLength: 1 minLength: 1
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
required: required:
- name - name
- private_key - private_key
@ -41182,6 +41206,18 @@ components:
api_url: api_url:
type: string type: string
minLength: 1 minLength: 1
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
PatchedCertificateKeyPairRequest: PatchedCertificateKeyPairRequest:
type: object type: object
description: CertificateKeyPair Serializer description: CertificateKeyPair Serializer

View File

@ -12,10 +12,10 @@
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0", "@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.38.1", "@wdio/cli": "^8.38.2",
"@wdio/local-runner": "^8.38.0", "@wdio/local-runner": "^8.38.2",
"@wdio/mocha-framework": "^8.38.0", "@wdio/mocha-framework": "^8.38.2",
"@wdio/spec-reporter": "^8.38.0", "@wdio/spec-reporter": "^8.38.2",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.25.1", "eslint-plugin-sonarjs": "^0.25.1",
@ -1189,19 +1189,19 @@
} }
}, },
"node_modules/@wdio/cli": { "node_modules/@wdio/cli": {
"version": "8.38.1", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.38.1.tgz", "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.38.2.tgz",
"integrity": "sha512-xif0RvJX+saXVdzrhlEafbEdptNyeyqm0pyilT4H7OI7OMa+23rWB67r2SPoIZbBrVeFv1iqtUx9hR73RRio2A==", "integrity": "sha512-p9y6jxmpmw53OoB9v/uTLwMetmz7Q0K7NewdVONgmeTY/ERpkU15qL3fMw1rXb+E+vrV8dlce4srnXroec6SFA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.1", "@types/node": "^20.1.1",
"@vitest/snapshot": "^1.2.1", "@vitest/snapshot": "^1.2.1",
"@wdio/config": "8.38.0", "@wdio/config": "8.38.2",
"@wdio/globals": "8.38.0", "@wdio/globals": "8.38.2",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0", "@wdio/protocols": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"chalk": "^5.2.0", "chalk": "^5.2.0",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
@ -1216,7 +1216,7 @@
"lodash.union": "^4.6.0", "lodash.union": "^4.6.0",
"read-pkg-up": "10.0.0", "read-pkg-up": "10.0.0",
"recursive-readdir": "^2.2.3", "recursive-readdir": "^2.2.3",
"webdriverio": "8.38.0", "webdriverio": "8.38.2",
"yargs": "^17.7.2" "yargs": "^17.7.2"
}, },
"bin": { "bin": {
@ -1239,14 +1239,14 @@
} }
}, },
"node_modules/@wdio/config": { "node_modules/@wdio/config": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.38.2.tgz",
"integrity": "sha512-9eMmHYkXw/0htj8Nok2vBa8Q+IS/wj7HXbLczKb5rEmDb57SW5iPMpZutFywGki1D/GIDLvejWaZvlxmS/yfBA==", "integrity": "sha512-xlnapTr1vOA0h5HsHTIqj47729FbG3WjxmgHweDEQvcT4C1g9l+WKf+N3FM7DNNoIsAqxKi6rOHG02rJADQJtw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"decamelize": "^6.0.0", "decamelize": "^6.0.0",
"deepmerge-ts": "^5.0.0", "deepmerge-ts": "^5.0.0",
"glob": "^10.2.2", "glob": "^10.2.2",
@ -1257,29 +1257,29 @@
} }
}, },
"node_modules/@wdio/globals": { "node_modules/@wdio/globals": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.38.2.tgz",
"integrity": "sha512-3Lo7R305gwJrloUolrgSRaMbIFKwnj/SPoYUt94dsTF1oM3TpyWpomcVokElNQiOFx9WYjMmBla2M+YcnoGmgw==", "integrity": "sha512-iIrUF1EODfHLh3V/CSNCqbNNxUTe3ND+c86zDjzJcPFjawLX1plvAApsU/eDmtsFShcOS2KHbfSjiydFoqQG1Q==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^16.13 || >=18" "node": "^16.13 || >=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"expect-webdriverio": "^4.11.2", "expect-webdriverio": "^4.11.2",
"webdriverio": "8.38.0" "webdriverio": "8.38.2"
} }
}, },
"node_modules/@wdio/local-runner": { "node_modules/@wdio/local-runner": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.38.2.tgz",
"integrity": "sha512-++eVI+EQapBMRxtLSbeooK02uELAhIXNLzgBlC03s23OTZUUOxzl4WxFuGqaG8gpNHer5Bjg+uAy0rIbSMnklA==", "integrity": "sha512-syW+R5VUHJ3GBkQGFcNYe6MYwWRgklc9W7A83xQDTvKWFNHCetLvc8AtKZ54vs8MItBejjU+Oh94ZNbNX1pBcg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.0", "@types/node": "^20.1.0",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/repl": "8.24.12", "@wdio/repl": "8.24.12",
"@wdio/runner": "8.38.0", "@wdio/runner": "8.38.2",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"split2": "^4.1.0", "split2": "^4.1.0",
"stream-buffers": "^3.0.2" "stream-buffers": "^3.0.2"
@ -1316,16 +1316,16 @@
} }
}, },
"node_modules/@wdio/mocha-framework": { "node_modules/@wdio/mocha-framework": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.2.tgz",
"integrity": "sha512-LWwKslKIxqhQNskdffcS6QbxN45PzJN21b5zByELbEYd9PIGNbuXXqueVE09RwEAzBHtL86ZhSpFclAB+ulsBw==", "integrity": "sha512-qJmRL5E6/ypjCUACH4hvCAAmTdU4YUrUlp9o/IKvTIAHMnZPE0/HgUFixCeu8Mop+rdzTPVBrbqxpRDdSnraYA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/mocha": "^10.0.0", "@types/mocha": "^10.0.0",
"@types/node": "^20.1.0", "@types/node": "^20.1.0",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"mocha": "^10.0.0" "mocha": "^10.0.0"
}, },
"engines": { "engines": {
@ -1351,14 +1351,14 @@
} }
}, },
"node_modules/@wdio/reporter": { "node_modules/@wdio/reporter": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.2.tgz",
"integrity": "sha512-7eyBM06j0PAu2g14wOwJbSmUOaT8q1pmMukzeRl1YDoW2sLpQG0zMZNzQNsQyi7+1KgltTJJnvHCec5MBZrjpw==", "integrity": "sha512-R78UdAtAnkaV22NYlCCcbPPhmYweiDURiw64LYhlVIQrKNuXUQcafR2kRlWKy31rZc9thSLs5LzrZDReENUlFQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.0", "@types/node": "^20.1.0",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"diff": "^5.0.0", "diff": "^5.0.0",
"object-inspect": "^1.12.0" "object-inspect": "^1.12.0"
}, },
@ -1367,35 +1367,35 @@
} }
}, },
"node_modules/@wdio/runner": { "node_modules/@wdio/runner": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.38.2.tgz",
"integrity": "sha512-pmoXwRMUxWXhqce64Y3gqoMqJn0YknJ1U9aHOMxp6uB3iHfzoPA+7Mf5ziSc0uDBcEyjXtau9qMfu7iBHUz62Q==", "integrity": "sha512-5lPnKSX2BBLI2AbYW+hoGPiEUAJXj8F8I6NC2LaBVzf1CLN+w2HWZ7lUiqS14XT0b5/hlSUX6+JYwUXlDbpuuw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.11.28", "@types/node": "^20.11.28",
"@wdio/config": "8.38.0", "@wdio/config": "8.38.2",
"@wdio/globals": "8.38.0", "@wdio/globals": "8.38.2",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"deepmerge-ts": "^5.1.0", "deepmerge-ts": "^5.1.0",
"expect-webdriverio": "^4.12.0", "expect-webdriverio": "^4.12.0",
"gaze": "^1.1.3", "gaze": "^1.1.3",
"webdriver": "8.38.0", "webdriver": "8.38.2",
"webdriverio": "8.38.0" "webdriverio": "8.38.2"
}, },
"engines": { "engines": {
"node": "^16.13 || >=18" "node": "^16.13 || >=18"
} }
}, },
"node_modules/@wdio/spec-reporter": { "node_modules/@wdio/spec-reporter": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.2.tgz",
"integrity": "sha512-Cuk/mqsBa+YgAL3OCtsYLUxRkGSYeaXM3LSE5muzY1mSqQlK3a/5GdAXlaOosuhYpUgI0A9xTsMiq7PQd75qHA==", "integrity": "sha512-Dntk+lmrp+0I3HRRWkkXED+smshvgsW5cdLKwJhEJ1liI48MdBpdNGf9IHTVckE6nfxcWDyFI4icD9qYv/5bFA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@wdio/reporter": "8.38.0", "@wdio/reporter": "8.38.2",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"chalk": "^5.1.2", "chalk": "^5.1.2",
"easy-table": "^1.2.0", "easy-table": "^1.2.0",
"pretty-ms": "^7.0.0" "pretty-ms": "^7.0.0"
@ -1417,9 +1417,9 @@
} }
}, },
"node_modules/@wdio/types": { "node_modules/@wdio/types": {
"version": "8.37.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.37.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.38.2.tgz",
"integrity": "sha512-36kmSlZcVhsMlbhaSCQUfL51iG81FlbzW4Dfkz4903cDkxmh64bgxydZbRB5aPLnJzzR7tI3chIME8zSVZFR8w==", "integrity": "sha512-+wj1c1OSLdnN4WO5b44Ih4263dTl/eSwMGSI4/pCgIyXIuYQH38JQ+6WRa+c8vJEskUzboq2cSgEQumVZ39ozQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.0" "@types/node": "^20.1.0"
@ -1429,14 +1429,14 @@
} }
}, },
"node_modules/@wdio/utils": { "node_modules/@wdio/utils": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.2.tgz",
"integrity": "sha512-ios7MpyJk4kGW9ZOYxbPpdwVZBI7SzccIgiirqSf8rvJi62VpDA2nfa7i7BY1rs9p7lnenF8phwnuVFGMCoL0w==", "integrity": "sha512-y5AnBwsGcu/XuCBGCgKmlvKdwEIFyzLA+Cr+denySxY3jbWDONtPUcGaVdFALwsIa5jcIjcATqGmZcCPGnkd7g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@puppeteer/browsers": "^1.6.0", "@puppeteer/browsers": "^1.6.0",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"decamelize": "^6.0.0", "decamelize": "^6.0.0",
"deepmerge-ts": "^5.1.0", "deepmerge-ts": "^5.1.0",
"edgedriver": "^5.5.0", "edgedriver": "^5.5.0",
@ -8969,18 +8969,18 @@
} }
}, },
"node_modules/webdriver": { "node_modules/webdriver": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.38.0.tgz", "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.38.2.tgz",
"integrity": "sha512-BT3sd667AqcZ1lzaOd7lphjnc7MNG3WgduAq4vUUDYlJAbs6SyjYd0EZPIPv9KUUYr0BoSJTDa0Xuyl/6PPW0Q==", "integrity": "sha512-NGfjW0BDYwFgOIzeojOcWGn3tYloQdvHr+Y2xKKYVqa9Rs0x1mzlTjU1kWtC4DaV8DltskwaPa7o+s8hTNpuyA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.0", "@types/node": "^20.1.0",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"@wdio/config": "8.38.0", "@wdio/config": "8.38.2",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0", "@wdio/protocols": "8.38.0",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"deepmerge-ts": "^5.1.0", "deepmerge-ts": "^5.1.0",
"got": "^12.6.1", "got": "^12.6.1",
"ky": "^0.33.0", "ky": "^0.33.0",
@ -8991,18 +8991,18 @@
} }
}, },
"node_modules/webdriverio": { "node_modules/webdriverio": {
"version": "8.38.0", "version": "8.38.2",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.38.0.tgz", "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.38.2.tgz",
"integrity": "sha512-PxLtJPK8Aa+f/G/P8YGUwGH80uHowMA8cDHshhog6sKbp1BXEVB8x6PyC1AIswRlTWVijoes7cD0cUoVs6C87A==", "integrity": "sha512-r09y5UfivyYh5JOzT2SpJJ1zDmQl/R4OTH12opUqkjvp21BibCQm/uu1mrxGy4lzSHljrvqSVrrcGI+6UA1O8w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/node": "^20.1.0", "@types/node": "^20.1.0",
"@wdio/config": "8.38.0", "@wdio/config": "8.38.2",
"@wdio/logger": "8.38.0", "@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0", "@wdio/protocols": "8.38.0",
"@wdio/repl": "8.24.12", "@wdio/repl": "8.24.12",
"@wdio/types": "8.37.0", "@wdio/types": "8.38.2",
"@wdio/utils": "8.38.0", "@wdio/utils": "8.38.2",
"archiver": "^7.0.0", "archiver": "^7.0.0",
"aria-query": "^5.0.0", "aria-query": "^5.0.0",
"css-shorthand-properties": "^1.1.1", "css-shorthand-properties": "^1.1.1",
@ -9020,7 +9020,7 @@
"resq": "^1.9.1", "resq": "^1.9.1",
"rgb2hex": "0.2.5", "rgb2hex": "0.2.5",
"serialize-error": "^11.0.1", "serialize-error": "^11.0.1",
"webdriver": "8.38.0" "webdriver": "8.38.2"
}, },
"engines": { "engines": {
"node": "^16.13 || >=18" "node": "^16.13 || >=18"

View File

@ -6,10 +6,10 @@
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0", "@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.38.1", "@wdio/cli": "^8.38.2",
"@wdio/local-runner": "^8.38.0", "@wdio/local-runner": "^8.38.2",
"@wdio/mocha-framework": "^8.38.0", "@wdio/mocha-framework": "^8.38.2",
"@wdio/spec-reporter": "^8.38.0", "@wdio/spec-reporter": "^8.38.2",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.25.1", "eslint-plugin-sonarjs": "^0.25.1",

8
web/package-lock.json generated
View File

@ -17,7 +17,7 @@
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.7", "@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.5.2", "@fortawesome/fontawesome-free": "^6.5.2",
"@goauthentik/api": "^2024.4.2-1717033226", "@goauthentik/api": "^2024.4.2-1717493155",
"@lit-labs/task": "^3.1.0", "@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.1", "@lit/context": "^1.1.1",
"@lit/localize": "^0.12.1", "@lit/localize": "^0.12.1",
@ -2968,9 +2968,9 @@
} }
}, },
"node_modules/@goauthentik/api": { "node_modules/@goauthentik/api": {
"version": "2024.4.2-1717033226", "version": "2024.4.2-1717493155",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.4.2-1717033226.tgz", "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.4.2-1717493155.tgz",
"integrity": "sha512-XMAY7k+cOGZF4hZMG01VtYXqnSH29wDT7qQ8R1Wg7WfDv2zo/LmwtDY4f/HGjbDo/6mxTo9WGl7wXTSCwgJqWQ==" "integrity": "sha512-+3jX2BUJLIlYVmUPtz4gQxRNd+k+IaGlc87t0JJPF3k9Zb4ZWFSp+garoHUkMtwz+6obCqbVaH/MH3Lbu6J4zw=="
}, },
"node_modules/@hcaptcha/types": { "node_modules/@hcaptcha/types": {
"version": "1.0.3", "version": "1.0.3",

View File

@ -38,7 +38,7 @@
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.7", "@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.5.2", "@fortawesome/fontawesome-free": "^6.5.2",
"@goauthentik/api": "^2024.4.2-1717033226", "@goauthentik/api": "^2024.4.2-1717493155",
"@lit-labs/task": "^3.1.0", "@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.1", "@lit/context": "^1.1.1",
"@lit/localize": "^0.12.1", "@lit/localize": "^0.12.1",

View File

@ -1,5 +1,7 @@
import { BaseStageForm } from "@goauthentik/admin/stages/BaseStageForm"; 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 "@goauthentik/components/ak-number-input";
import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
@ -78,6 +80,40 @@ export class CaptchaStageForm extends BaseStageForm<CaptchaStage> {
)} )}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-number-input
label=${msg("Score minimum threshold")}
required
name="scoreMinThreshold"
value="${ifDefined(this.instance?.scoreMinThreshold || 0.5)}"
help=${msg("Minimum required score to allow continuing")}
></ak-number-input>
<ak-number-input
label=${msg("Score maximum threshold")}
required
name="scoreMaxThreshold"
value="${ifDefined(this.instance?.scoreMaxThreshold || -1)}"
help=${msg("Maximum allowed score to allow continuing")}
></ak-number-input>
<ak-form-element-horizontal name="errorOnInvalidScore">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.errorOnInvalidScore, true)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${msg("Error on invalid score")}</span>
</label>
<p class="pf-c-form__helper-text">
${msg(
"When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.",
)}
</p>
</ak-form-element-horizontal>
</div> </div>
</ak-form-group> </ak-form-group>
<ak-form-group> <ak-form-group>

View File

@ -72,16 +72,6 @@ Set when a flow execution is continued from a token. This happens for example wh
### Stage-specific keys ### Stage-specific keys
#### Consent stage
##### `consent_header` (string)
The title of the consent prompt shown. Set automatically when the consent stage is used with a OAuth2, Proxy or SAML provider.
##### `consent_permissions` (List of PermissionDict)
An optional list of all permissions that will be given to the application by granting consent. Not supported with SAML. When used with an OAuth2 or Proxy provider, this will be set based on the configured scopes.
#### Autosubmit stage #### Autosubmit stage
The autosubmit stage is an internal stage type that is not configurable via the API/Web interface. It is used in certain situations, where a POST request is sent from the browser, such as with SAML POST bindings. This works by using an HTML form that is submitted automatically. The autosubmit stage is an internal stage type that is not configurable via the API/Web interface. It is used in certain situations, where a POST request is sent from the browser, such as with SAML POST bindings. This works by using an HTML form that is submitted automatically.
@ -98,6 +88,28 @@ URL that the form will be submitted to.
Key-value pairs of the data that is included in the form and will be submitted to `url`. Key-value pairs of the data that is included in the form and will be submitted to `url`.
#### Captcha stage
:::info
Requires authentik 2024.6
:::
##### `captcha` (dictionary)
When `error_on_invalid_score` (TODO) is set to false on a captcha stage, after the execution of the captcha stage, this object will be set in the flow context.
It contains two keys, `response` which is the raw response from the specified captcha verification URL, and `stage`, which is a reference to the captcha stage that executed the test.
#### Consent stage
##### `consent_header` (string)
The title of the consent prompt shown. Set automatically when the consent stage is used with a OAuth2, Proxy or SAML provider.
##### `consent_permissions` (List of PermissionDict)
An optional list of all permissions that will be given to the application by granting consent. Not supported with SAML. When used with an OAuth2 or Proxy provider, this will be set based on the configured scopes.
#### Deny stage #### Deny stage
##### `deny_message` (string) ##### `deny_message` (string)

View File

@ -8,16 +8,35 @@ This stage adds a form of verification using [Google's ReCaptcha](https://www.go
- hCaptcha - hCaptcha
- Turnstile - Turnstile
## 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.
![](captcha-admin.png) ![](captcha-admin.png)
#### Configuration options
- JS URL: `https://www.recaptcha.net/recaptcha/api.js`
- API URL: `https://www.recaptcha.net/recaptcha/api/siteverify`
- Score minimum threshold: `0.5`
- Score maximum threshold: `1`
### hCaptcha ### hCaptcha
See https://docs.hcaptcha.com/switch See https://docs.hcaptcha.com/switch
#### Configuration options
- JS URL: `https://js.hcaptcha.com/1/api.js`
- API URL: `https://api.hcaptcha.com/siteverify`
**Score options only apply to hCaptcha Enterprise**
- Score minimum threshold: `0`
- Score maximum threshold: `0.5`
### Turnstile ### Turnstile
See https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha See https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha
@ -25,3 +44,10 @@ See https://developers.cloudflare.com/turnstile/get-started/migrating-from-recap
:::warning :::warning
To use Cloudflare Turnstile, the site must be configured to use the "Invisible" mode, otherwise the widget will be rendered incorrectly. To use Cloudflare Turnstile, the site must be configured to use the "Invisible" mode, otherwise the widget will be rendered incorrectly.
::: :::
#### Configuration options
- JS URL: `https://challenges.cloudflare.com/turnstile/v0/api.js`
- API URL: `https://challenges.cloudflare.com/turnstile/v0/siteverify`
**Score options do not apply when using with turnstile**

View File

@ -37,7 +37,7 @@ The following outpost settings are used:
## Permissions ## Permissions
The permissions required for this integration are documented in the helm chart, see [Cluster-level](https://github.com/goauthentik/helm/blob/main/charts/authentik-remote-cluster/templates/cluster-role-binding.yaml) and [Namespace-level](https://github.com/goauthentik/helm/blob/main/charts/authentik-remote-cluster/templates/role-binding.yaml). The permissions required for this integration are documented in the helm chart. See [Cluster-level](https://github.com/goauthentik/helm/blob/main/charts/authentik-remote-cluster/templates/clusterrolebinding.yaml) and [Namespace-level](https://github.com/goauthentik/helm/blob/main/charts/authentik-remote-cluster/templates/rolebinding.yaml).
## Remote clusters ## Remote clusters